How to stop scrolling an element in a Recycler view after reaching a certain distance

I have a Recycler view in android. I connected to it ItemTouchHelper. I turned on only scrolling from left to right.

Therefore, when I scroll through any element of the Recycler view, the element starts to move to the right, and on the left I draw text. It is perfectly. My requirement is that I want the user to be able to travel some distance, and when that distance is reached and the user releases the touch, the item to be scrolled should return to its left position.

The problem is that when scrolling left and right, the view is completely squeezed out of the screen. How can I limit it to scrolling only a certain distance? How to do it?

Here is my code for a callback of a tap on an element:

private void initSwipe(){
    ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                int position = viewHolder.getAdapterPosition();
            }

        @Override
        public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
            ViewHolder viewHolder1 = (ViewHolder)viewHolder;
            int position = viewHolder1.getAdapterPosition();
            MyItem item = dataList.get(position);
            if (item==null )return;
            if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){

                View itemView = viewHolder.itemView;
                float height = (float) itemView.getBottom() - (float) itemView.getTop();
                float width = height / 3;
                Paint p = new Paint();
                Paint textPaint = new Paint();
                textPaint.setColor(Color.WHITE);
                textPaint.setTextSize(20);

                if(dX > 0) {
                    p.setColor(Color.parseColor("#000000"));
                    RectF background = new RectF((float) itemView.getLeft(), (float) itemView.getTop(), dX,(float) itemView.getBottom());
                    c.drawRect(background,p);
                    //RectF icon_dest = new RectF((float) itemView.getLeft() + width ,(float) itemView.getTop() + width,(float) itemView.getLeft()+ 2*width,(float)itemView.getBottom() - width);
                    //c.drawBitmap(icon,null,icon_dest,p);
                    c.drawText(item.getDate(),(float)(itemView.getLeft() + width),(float)(itemView.getBottom() - width), textPaint);
                }
            }
            super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        }
    };
    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
    itemTouchHelper.attachToRecyclerView(myRecycler);
}`
+6
source share
1 answer

Replace this line in onChildDraw:

super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);

using the following, it sets the maximum x position to 100, adjust this value according to your needs.

float newDx = dX;
if (newDx >= 100f) {
    newDx = 100f
}
super.onChildDraw(c, recyclerView, viewHolder, newDx, dY, actionState, isCurrentlyActive);

Then in the onSwiped callback handler, call notifyItemChanged for the RecyclerView adapter.

 @Override
 public void onSwiped(RecyclerView.ViewHolder viewHolder,
     int direction) {
         if (direction == ItemTouchHelper.RIGHT) {
        adapter.notifyItemChanged(viewHolder.getAdapterPosition())
    }
 }

A small problem with notifyItemChanged is that you may notice a quick blink when the view is restored to its original position.

+3
source

Source: https://habr.com/ru/post/1690952/


All Articles