如何在RecyclerView中进行假滑动

问题描述 投票:0回答:1

就像那些你无法解雇的通知:你向中间滑动,然后停止。有谁知道如何在RecyclerView中做到这一点?

如果你不记得了: https://youtu.be/eFvhFkZfGlA

android android-recyclerview swipe
1个回答
2
投票
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            return false;
        }

        @Override
        public float getSwipeThreshold(RecyclerView.ViewHolder viewHolder) {
            return 1;
        }
    };

    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
    itemTouchHelper.attachToRecyclerView(recyclerView);

这里的关键部分是getSwipeThreshold方法 。

---------------------------------- 编辑:实际上,还有更多的东西,我找不到一种方法来完全实现所要求的(完全像视频和Android通知栏),但由于我在这里有一个错误的答案,我决定编辑我的帖子并实现与它非常相似的东西。

除了提到的内容以及要在ItemTouchHelper.SimpleCallback类中添加的字段之外,还有其他方法可以被覆盖。

领域:

        private final float stopPoint = 200;                // The point where items stop when move past it
        private final float swipeStopFraction = 0.002f;     // higher means items stop sooner when swiped
        private final float swipeSpeedFraction = 0.8f;      // lower means items move slower when swiped

        private float prevA = 1;
        private float a = 1;

        private float prevDX;
        private float backDX;

        private boolean leftLock = false;
        private boolean rightLock = false;
        private boolean leftExpanded = false;
        private boolean rightExpanded = false;

        private CustomRecyclerViewAdapter.CustomViewHolder prevHolder;

其他方法:

      @Override
      public float getSwipeVelocityThreshold(float defaultValue) {
            return 0;
        }

      @Override
      public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
            final CustomRecyclerViewAdapter.CustomViewHolder holder = (CustomRecyclerViewAdapter.CustomViewHolder) viewHolder;
            prevHolder = holder;

            dX *= swipeSpeedFraction;

            if (!isCurrentlyActive) {
                if (!leftLock) {
                    leftExpanded = false;
                }
                if (!rightLock) {
                    rightExpanded = false;
                }
                a = 0;
            }

            if (isCurrentlyActive) {
                if (dX > 0 && !rightExpanded) {
                    leftExpanded = true;
                }
                if (dX < 0 && !leftExpanded) {
                    rightExpanded = true;
                }
            }

            float cachedDX = dX;
            if (a == 0) {
                if (dX / prevA > stopPoint && !rightExpanded && backDX == 0) {
                    leftLock = true;
                    leftExpanded = true;
                }
                if (dX / prevA < -stopPoint && !leftExpanded && backDX == 0) {
                    rightLock = true;
                    rightExpanded = true;
                }
                if (backDX != 0) {
                    dX += backDX - dX;
                    backDX /= 2;
                } else {
                    dX /= prevA;
                }
                a = 1;
            } else if (dX == 0) {
                backDX = 0;
            } else if (dX > 0) {
                if (leftExpanded) {
                    if (backDX != 0) {
                        leftLock = true;
                    }
                    dX /= a;
                    prevA = a;
                    a += swipeStopFraction * (cachedDX - prevDX);
                } else {
                    dX = - stopPoint + dX;
                    if (backDX > 0) {
                        a += 0.01 * (cachedDX - prevDX);
                    }
                    dX /= a;
                    backDX = dX;
                    rightLock = false;
                }
            } else if (dX < 0) {
                if (rightExpanded) {
                    if (backDX != 0) {
                        rightLock = true;
                    }
                    dX /= a;
                    prevA = a;
                    a -= swipeStopFraction * (cachedDX - prevDX);
                } else  {
                    dX = stopPoint + dX;
                    if (backDX < 0) {
                        a -= 0.01 * (cachedDX - prevDX);
                    }
                    dX /= a;
                    prevA = a;
                    backDX = dX;
                    leftLock = false;
                }
            }
            prevDX = cachedDX;

            if (leftLock) {
                if (dX < stopPoint) {
                    dX = stopPoint;
                }
            }

            if (rightLock) {
                if (dX > -stopPoint) {
                    dX = -stopPoint;
                }
            }

            // Below lines provide background for the empty area when the item is swiped.
            // Container could be any layout that is the root layout if the item
            final Paint paint = new Paint();
            paint.setColor(getResources().getColor(R.color.colorAccent));
            if (dX > 0) {
                c.drawRect(holder.container.getLeft(), holder.container.getTop(), dX, holder.container.getBottom(), paint);
            } else {
                c.drawRect(holder.container.getRight() + dX, holder.container.getTop(), holder.container.getRight(), holder.container.getBottom(), paint);
            }


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

        @Override
        public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
            super.onSelectedChanged(viewHolder, actionState);

            if (prevHolder != null && viewHolder != null && prevHolder != viewHolder) {
                leftLock = false;
                rightLock = false;
                leftExpanded = false;
                rightExpanded = false;
                prevHolder.container.setTranslationX(0);  // Container could be any layout that is the root layout of the item
            }

        }

对回收者视图中发生的事情的控制是非常有限的,我不能再推动它了。我希望这可能会有所帮助。

就个人而言,我认为使用ItemTouchHelper这样做很难实现和管理,结果不会那么容易接受。

© www.soinside.com 2019 - 2024. All rights reserved.