I will describe what I think may be relevant to the problem.
There is a RecyclerView filled with objects from CardView and TextView. In the onBindViewHolder() method, the TextView visibility change method is called:

 void setItemText(ViewHolder viewHolder, Item item) { super.setItemText(viewHolder, item); if (mModel.isShowcaseNamesShow()) { viewHolder.mName.setVisibility(View.VISIBLE); } else { viewHolder.mName.setVisibility(View.GONE); } } 

The GestureDetector is registered in the Activity to process the Fling gesture, which changes the width of the layout with RecyclerView and the state of change isShowcaseNamesShow , and also causes the adapter to notifyDataSetChanged() to update the content.
The touch event is passed to the GestureDetector in the dispatchTouchEvent() method. Activity:

 @Override public boolean dispatchTouchEvent(MotionEvent event) { mGestureDetector.onTouchEvent(event); return super.dispatchTouchEvent(event); } 

As a result, if the RecyclerView touches during Fling, then it scrolls, and the objects in it jump, hang in the wrong places and are crookedly displayed (see screenshots below):

This is, in fact, the problem. What happens and how to fix it? Originally used ListView instead of RecyclerView, there were no such frills.
It may be worth noting that I use the stable id in the adapter ( setHasStableIds(true) ), overriding the method:

 @Override public long getItemId(int position) { int nameRes = mItems.get(position).getNameRes(); if (nameRes != 0) return nameRes; else return mItems.get(position).getName().hashCode(); } 

Tried to resolve the issue as follows - do not transmit a touch event further if Fling is triggered:

 @Override public boolean dispatchTouchEvent(MotionEvent event) { if (mGestureDetector.onTouchEvent(event)) return true; else return super.dispatchTouchEvent(event); } 

The conflict is resolved, but it does not suit me, as it leads to other problems due to the loss of touch events (for example, the onTouchListener of other RecyclerView objects is silent when detecting Fling)

PS For the first time I ask a programming question, so I apologize for the large volume and water, did not know how to cut it). And yes, I started to learn Android recently, my first application, if I do something wrong or I think I would like to hear advice and objective criticism.

    1 answer 1

    I solved the problem like this: instead of intercepting a touch event in a dispatchTouchEvent , the Activity hooked the OnItemTouchListener listener to the RecyclerView directly:

     mRecyclerView.addOnItemTouchListener(new ItemTouchListener()); 

    Listener ID:

     class ItemTouchListener extends RecyclerView.SimpleOnItemTouchListener { @Override public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { return mGestureDetector.onTouchEvent(e); } } 

    The touch event first comes to onInterceptTouchEvent and is intercepted when the Fling gesture is made, otherwise it goes further to handle scrolling in the RecyclerView system.