title: RecyclerView and ItemTouchHelper swipe to remove issue
body: <p>I'm trying to implement "swipe to remove" feature via RecyclerView and ItemTouchHelper. I have a strange problem and I can't locate the issue for the life of me. I swipe an item away from the top (not the very first one), it goes away, so far so good. When I scroll away and come back, there is an artefact in the row above swiped away item. Looks like that row is not drawn (or maybe is x translated?). Video shows the issue.</p>
  
  <p>Steps of the video:</p>
  
  <ol>
  <li>I swipe away Item 2</li>
  <li>Scroll down to the bottom</li>
  <li>Come back</li>
  <li>Item 1 is no longer visible</li>
  <li>I scroll down to the bottom again</li>
  <li>I scroll back up</li>
  <li>Everything is fine now</li>
  <li>Again, but with a third (not the second) item from the top, same problem</li>
  <li>Again, with the very first item, no issue</li>
  </ol>
  
  <p><img src="https://i.stack.imgur.com/SDBr4.gif" alt="enter image description here"></p>
  
  <p>Relevant code: (whole github sample app <a href="https://github.com/nemanja-kovacevic/recycler-view-swipe-to-remove-problem" rel="nofollow noreferrer">here</a>)</p>
  
  <pre><code>public class MainActivity extends AppCompatActivity {
  
  RecyclerView mRecyclerView;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
      setSupportActionBar(toolbar);
      mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
      mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
      mRecyclerView.setAdapter(new TestAdapter());
      setUpItemTouchHelper();
  
  }
  
  private void setUpItemTouchHelper() {
      ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
  
          @Override
          public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
              return false;
          }
  
          @Override
          public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
              int swipedPosition = viewHolder.getAdapterPosition();
              TestAdapter adapter = (TestAdapter)mRecyclerView.getAdapter();
              adapter.remove(swipedPosition);
          }
  
      };
      ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
      itemTouchHelper.attachToRecyclerView(mRecyclerView);
  }
  
  static class TestAdapter extends RecyclerView.Adapter {
  
      List&lt;String&gt; items;
  
      public TestAdapter() {
          items = new ArrayList&lt;&gt;();
          // this should give us a couple of screens worth
          for (int i=1; i&lt;= 15; i++) {
              items.add("Item " + i);
          }
      }
  
      @Override
      public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
          return new TestViewHolder(parent);
      }
  
      @Override
      public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
          TestViewHolder viewHolder = (TestViewHolder)holder;
          String item = items.get(position);
          viewHolder.titleTextView.setText(item);
      }
  
      @Override
      public int getItemCount() {
          return items.size();
      }
  
      public void remove(int position) {
          if (position &lt; 0 || position &gt;= items.size()) {
              return;
          }
          items.remove(position);
          notifyItemRemoved(position);
      }
  }
  
  static class TestViewHolder extends RecyclerView.ViewHolder {
  
      TextView titleTextView;
  
      public TestViewHolder(ViewGroup parent) {
          super(LayoutInflater.from(parent.getContext()).inflate(R.layout.row_view, parent, false));
          titleTextView = (TextView) itemView.findViewById(R.id.title_text_view);
      }
  
  }
  
  }
  </code></pre>
  
  <p>EDIT:</p>
  
  <p>I have a hack that removes this glitch, but still I want to know the cause and how can I really fix the issue. The hack is calling notifyDataSetChanged() but after the animations are done (otherwise animation gets terminated). Basically I add an ItemDecorator and figure out that an animation ended.</p>
  
  <pre><code>mRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
  
          boolean running;
  
          @Override
          public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
              if (parent.getItemAnimator().isRunning()) {
                  running = true;
              }
              if (running == true &amp;&amp; !parent.getItemAnimator().isRunning()) {
                  // first time it's not running
                  running = false;
                  parent.getAdapter().notifyDataSetChanged();
              }
              super.onDraw(c, parent, state);
          }
  });
  </code></pre>