title: How to handle clicks on the rows of listView, while notifyDataSetChanged might be called?
body: <h2>Background</h2>
  
  <p>I have a complex adapter for a listView.</p>
  
  <p>Each row has some inner views that need to be clickable (and hande the clicks), and they also have selectors (to show the effect of touching).</p>
  
  <p>on some cases, notifyDataSetChanged() needs to be called quite frequently (for example once/twice a second), to show some changes on the listView's items.</p>
  
  <p>As an example, consider seeing a list of downloading files, where you show the user the progress of each file being downloaded.</p>
  
  <h2>The problem</h2>
  
  <p>Each time notifyDataSetChanged is called, the touch event is lost on the touched view, so the user can miss clicking on it , and especially miss long clicking on it.</p>
  
  <p>Not only that, but the selector also loses its state, so if you touch it and see the effect, when the notifyDataSetChanged is called, the view loses its state and you see it as if it isn't get touched.</p>
  
  <p>This happens even for views that have nothing in them being updated (meaning I just return the convertView for them) .</p>
  
  <h2>Sample code</h2>
  
  <p>The code below demonstrates the problem. It is not the original code but a super short sample to make it clear what I'm talking about.</p>
  
  <p>Again, this is not the original code, so I've removed the ViewHolder usage and taking care of the clicking to do some operations, in order to make it simple to read and understand. But it's still the same logic.</p>
  
  <p>Here's the code:</p>
  
  <p><strong>MainActivity.java</strong></p>
  
  <pre><code>public class MainActivity extends ActionBarActivity {
  
      @Override
      protected void onCreate(final Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          final ListView listView = (ListView) findViewById(R.id.listView);
          final BaseAdapter adapter = new BaseAdapter() {
  
              @Override
              public View getView(final int position, final View convertView, final ViewGroup parent) {
                  TextView tv = (TextView) convertView;
                  if (tv == null) {
                      tv = new TextView(MainActivity.this);
                      tv.setBackgroundDrawable(getResources().getDrawable(R.drawable.item_background_selector));
                      tv.setOnClickListener(new OnClickListener() {
  
                          @Override
                          public void onClick(final View v) {
                              android.util.Log.d("AppLog", "click");
                          }
                      });
                  }
                  //NOTE: putting the setOnClickListener here won't help either.
                  final int itemViewType = getItemViewType(position);
                  tv.setText((itemViewType == 0 ? "A " : "B ") + System.currentTimeMillis());
                  return tv;
              }
  
              @Override
              public int getItemViewType(final int position) {
                  return position % 2;
              }
  
              @Override
              public long getItemId(final int position) {
                  return position;
              }
  
              @Override
              public Object getItem(final int position) {
                  return null;
              }
  
              @Override
              public int getCount() {
                  return 100;
              }
  
              @Override
              public boolean areAllItemsEnabled() {
                  return false;
              }
  
              @Override
              public boolean isEnabled(final int position) {
                  return false;
              }
          };
          listView.setAdapter(adapter);
          final Handler handler = new Handler();
          handler.postDelayed(new Runnable() {
  
              @Override
              public void run() {
                  // fake notifying
                  adapter.notifyDataSetChanged();
                  android.util.Log.d("AppLog", "notifyDataSetChanged");
                  handler.postDelayed(this, 1000);
              }
          }, 1000);
      }
  }
  </code></pre>
  
  <p><strong>item_background_selector.xml</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&gt;
  
      &lt;item android:state_pressed="true"&gt;&lt;shape&gt;
              &lt;solid android:color="@android:color/holo_blue_light" /&gt;
          &lt;/shape&gt;&lt;/item&gt;
      &lt;item android:state_focused="true"&gt;&lt;shape&gt;
              &lt;solid android:color="@android:color/holo_blue_light" /&gt;
          &lt;/shape&gt;&lt;/item&gt;
      &lt;item android:drawable="@android:color/transparent"/&gt;
  
  &lt;/selector&gt;
  </code></pre>
  
  <p><strong>activity_main.xml</strong></p>
  
  <pre><code>&lt;FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:id="@+id/container"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      tools:context="com.example.test.MainActivity"
      tools:ignore="MergeRootFrame" &gt;
  
      &lt;ListView
          android:id="@+id/listView"
          android:layout_width="match_parent"
          android:layout_height="match_parent" &gt;
      &lt;/ListView&gt;
  
  &lt;/FrameLayout&gt;
  </code></pre>
  
  <h2>Partial solution</h2>
  
  <p>It's possible to update only the needed views, by finding the view and then calling getView on it, but this is a workaround.
  Also, it won't work in the case of adding/removing items from the listView, which needs to have notifyDataSetChangedbeing called. Plus it also makes the updated view to lose its touching state.</p>
  
  <p>EDIT: even the partial solution doesn't work. Maybe it's causing a layout of the entire listView, which causes the other views to lose their states. </p>
  
  <h2>The question</h2>
  
  <p>How can I let views stay "in sync" with the touch events after calling notifyDataSetChanged() ? </p>