Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>My solution: If it is correct*, update the data and viewable items without re-drawing the whole list. Else notifyDataSetChanged.</p> <p>Correct - oldData size == new data size, and old data IDs and their order == new data IDs and order</p> <p>How:</p> <pre><code>/** * A View can only be used (visible) once. This class creates a map from int (position) to view, where the mapping * is one-to-one and on. * */ private static class UniqueValueSparseArray extends SparseArray&lt;View&gt; { private final HashMap&lt;View,Integer&gt; m_valueToKey = new HashMap&lt;View,Integer&gt;(); @Override public void put(int key, View value) { final Integer previousKey = m_valueToKey.put(value,key); if(null != previousKey) { remove(previousKey);//re-mapping } super.put(key, value); } } @Override public void setData(final List&lt;? extends DBObject&gt; data) { // TODO Implement 'smarter' logic, for replacing just part of the data? if (data == m_data) return; List&lt;? extends DBObject&gt; oldData = m_data; m_data = null == data ? Collections.EMPTY_LIST : data; if (!updateExistingViews(oldData, data)) notifyDataSetChanged(); else if (DEBUG) Log.d(TAG, "Updated without notifyDataSetChanged"); } /** * See if we can update the data within existing layout, without re-drawing the list. * @param oldData * @param newData * @return */ private boolean updateExistingViews(List&lt;? extends DBObject&gt; oldData, List&lt;? extends DBObject&gt; newData) { /** * Iterate over new data, compare to old. If IDs out of sync, stop and return false. Else - update visible * items. */ final int oldDataSize = oldData.size(); if (oldDataSize != newData.size()) return false; DBObject newObj; int nVisibleViews = m_visibleViews.size(); if(nVisibleViews == 0) return false; for (int position = 0; nVisibleViews &gt; 0 &amp;&amp; position &lt; oldDataSize; position++) { newObj = newData.get(position); if (oldData.get(position).getId() != newObj.getId()) return false; // iterate over visible objects and see if this ID is there. final View view = m_visibleViews.get(position); if (null != view) { // this position has a visible view, let's update it! bindView(position, view, false); nVisibleViews--; } } return true; } </code></pre> <p>and of course:</p> <pre><code>@Override public View getView(final int position, final View convertView, final ViewGroup parent) { final View result = createViewFromResource(position, convertView, parent); m_visibleViews.put(position, result); return result; } </code></pre> <p>Ignore the last param to bindView (I use it to determine whether or not I need to recycle bitmaps for ImageDrawable).</p> <p>As mentioned above, the total number of 'visible' views is roughly the amount that fits on the screen (ignoring orientation changes etc), so no biggie memory-wise.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload