简体   繁体   English

如何使用 SnapHelper 将快照 position 从 RecycleView 的中心移动到左侧?

[英]How to move the snap position from center to left of RecycleView using SnapHelper?

I have an RecycleView that contains ImageViews and my question is how can i move the snap to be on the left side of the RecycleView instead of the center?我有一个包含 ImageView 的 RecycleView,我的问题是如何将快照移动到 RecycleView 的左侧而不是中心?

When i move the ImageViews they get snapped in the center and I can move them to the left or right inside that "snap window" by overriding the CalculateDistanceToFinalSnap method.当我移动 ImageViews 时,它们会在中心捕捉,我可以通过覆盖CalculateDistanceToFinalSnap方法将它们移动到该“捕捉窗口”内的左侧或右侧。 I think I would now need to move that "snap window" to the left side of the RecycleView but I don't know how, or maybe there is another way, please help.我想我现在需要将那个“快照窗口”移动到 RecycleView 的左侧,但我不知道如何,或者也许还有另一种方法,请帮忙。

Here is a image of my problem, maybe it will help you to understand more clearly: image这是我的问题的图片,也许它会帮助您更清楚地理解:图片

@Jessie Zhang -MSFT's solution works for me. @Jessie Zhang -MSFT 的解决方案对我有用。 The code was a little oddly formatted and I had some difficulty bringing it over.代码的格式有点奇怪,我很难把它拿过来。 Here is the same solution (for a horizontal snap only) in Kotlin.这是 Kotlin 中的相同解决方案(仅适用于水平捕捉)。

class StartSnapHelper: LinearSnapHelper() {
    override fun calculateDistanceToFinalSnap(layoutManager: RecyclerView.LayoutManager, targetView: View): IntArray? {
        return if (layoutManager.canScrollHorizontally()) {
            val outer = mutableListOf<Int>()
            outer.add(distanceToStart(targetView, getHorizontalHelper(layoutManager)))
            outer.add(0)

            outer.toIntArray()
        } else {
            super.calculateDistanceToFinalSnap(layoutManager, targetView)
        }
    }

    override fun findSnapView(layoutManager: RecyclerView.LayoutManager?): View? {
        return if (layoutManager is LinearLayoutManager) {
            if (layoutManager.canScrollHorizontally()) {
            getStartView(layoutManager, getHorizontalHelper(layoutManager))
            } else {
                super.findSnapView(layoutManager)
            }
        } else {
            super.findSnapView(layoutManager)
        }
    }

    private fun distanceToStart(targetView: View, helper: OrientationHelper): Int {
        return helper.getDecoratedStart(targetView) - helper.startAfterPadding
    }

    private fun getStartView(layoutManager: RecyclerView.LayoutManager, orientationHelper: OrientationHelper): View? {
        val firstChild = (layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
        val isLastItem = (layoutManager.findLastCompletelyVisibleItemPosition() == layoutManager.itemCount - 1)

        if (firstChild == RecyclerView.NO_POSITION || isLastItem) {
            return null
        }

        val child = layoutManager.findViewByPosition(firstChild)

        return if (orientationHelper.getDecoratedEnd(child) >= orientationHelper.getDecoratedMeasurement(child) / 2
        && orientationHelper.getDecoratedEnd(child) > 0) {
        child;
        } else {
            if (layoutManager.findFirstCompletelyVisibleItemPosition() == layoutManager.itemCount -1) {
                null
            } else {
                layoutManager.findViewByPosition(firstChild + 1)
            }
        }
    }

    private fun getHorizontalHelper(layoutManager: RecyclerView.LayoutManager): OrientationHelper {
        return OrientationHelper.createHorizontalHelper(layoutManager)
    }
}

I have achieved this function ,we juse need to create a class and extent class LinearSnapHelper and override method CalculateDistanceToFinalSnap and FindSnapView .我已经实现了这个功能,我们需要创建一个类和范围类LinearSnapHelper并覆盖方法CalculateDistanceToFinalSnapFindSnapView You can check out the full demo here .您可以在此处查看完整的演示。

The main code is as follows:主要代码如下:

 public class StartSnapHelper: LinearSnapHelper
 {
    private OrientationHelper mVerticalHelper, mHorizontalHelper;

    public StartSnapHelper()
    {
    }

    public override void AttachToRecyclerView(RecyclerView recyclerView)
    {
        base.AttachToRecyclerView(recyclerView);
    }

    public override int[] CalculateDistanceToFinalSnap(RecyclerView.LayoutManager layoutManager, View targetView)
    {
        //return base.CalculateDistanceToFinalSnap(layoutManager, targetView);
        int[] outer = new int[2];

        if (layoutManager.CanScrollHorizontally())
        {
            outer[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager));
        } else {
            outer[0] = 0;
        }

    if (layoutManager.CanScrollVertically()) {
            outer[1] = distanceToStart(targetView, getVerticalHelper(layoutManager));
    } else {
            outer[1] = 0;
    }
    return outer;
    }

    private int distanceToStart(View targetView, OrientationHelper helper)
    {
        return helper.GetDecoratedStart(targetView) - helper.StartAfterPadding;
    }

    public override View FindSnapView(RecyclerView.LayoutManager layoutManager)
    {
        if (layoutManager is LinearLayoutManager) {

            if (layoutManager.CanScrollHorizontally())
            {
                return getStartView(layoutManager, getHorizontalHelper(layoutManager));
            }
            else
            {
                return getStartView(layoutManager, getVerticalHelper(layoutManager));
            }
        }

        return base.FindSnapView(layoutManager);
    }

    private View getStartView(RecyclerView.LayoutManager layoutManager,
                          OrientationHelper helper)
    {

        if (layoutManager is LinearLayoutManager) {
            int firstChild = ((LinearLayoutManager)layoutManager).FindFirstVisibleItemPosition();

            bool isLastItem = ((LinearLayoutManager)layoutManager)
                    .FindLastCompletelyVisibleItemPosition()
                    == layoutManager.ItemCount - 1;

            if (firstChild == RecyclerView.NoPosition || isLastItem)
            {
                return null;
            }

            View child = layoutManager.FindViewByPosition(firstChild);

            if (helper.GetDecoratedEnd(child) >= helper.GetDecoratedMeasurement(child) / 2
                    && helper.GetDecoratedEnd(child) > 0)
            {
                return child;
            }
            else
            {
                if (((LinearLayoutManager)layoutManager).FindLastCompletelyVisibleItemPosition()
                        == layoutManager.ItemCount - 1)
                {
                    return null;
                }
                else
                {
                    return layoutManager.FindViewByPosition(firstChild + 1);
                }
            }
        }
        return base.FindSnapView(layoutManager);
    }


    private OrientationHelper getVerticalHelper(RecyclerView.LayoutManager layoutManager)
    {
        if (mVerticalHelper == null)
        {
            mVerticalHelper = OrientationHelper.CreateVerticalHelper(layoutManager);
        }
        return mVerticalHelper;
    }

    private OrientationHelper getHorizontalHelper(RecyclerView.LayoutManager layoutManager)
    {
        if (mHorizontalHelper == null)
        {
            mHorizontalHelper = OrientationHelper.CreateHorizontalHelper(layoutManager);
        }
        return mHorizontalHelper;
    }
}

And use like this:并像这样使用:

  SnapHelper snapHelperStart = new StartSnapHelper();
  snapHelperStart.AttachToRecyclerView(recyclerView);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 Snaphelper 更改中心元素的背景颜色 - How to change background color of center element using Snaphelper 如何从RecyclerView中删除SnapHelper - How to remove SnapHelper from a RecyclerView 带有 snaphelper 的水平回收器视图,如何将第一个和最后一个元素居中? - Horizontal recyclerview with snaphelper, how to center first and last element? SnapHelper 项目位置 - SnapHelper Item Position 如何从 RecycleView Android 中获取过滤数据的新 Position - How to get the new Position of Filtered Data from RecycleView Android 如何在 RecyclerView 中使用 SnapHelper - How to use SnapHelper with RecyclerView RecyclerView / SnapHelper-如何设置卡片的可变位置,以便根据位置不同地窥视 - RecyclerView/SnapHelper - How to set variable position of the cards so that they peek differently based on position 如何将Recycleview项目移动到导航抽屉的片段? - How to move Recycleview item to Fragment of navigation Drawer? 如何从菜单列表中使用RecycleView Android进行gridlayout和linearlayout - How to have gridlayout and linearlayout using RecycleView Android from Menu list RecyclerView SnapHelper查找被捕捉项目的确切位置 - RecyclerView SnapHelper find the exact position of snapped item
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM