【问题标题】:LinearSnapHelper doesn't snap on edge items of RecyclerViewLinearSnapHelper 不会捕捉 RecyclerView 的边缘项目
【发布时间】:2017-06-26 18:21:12
【问题描述】:

这是我之前的question 的后续。

在我的应用程序中,我试图让水平的RecyclerView 自动捕捉到中心项目。为此,我附上了LinearSnapHelper。我还创建了一个项目装饰,为第一个/最后一个元素添加了一些左/右填充:

public class OffsetItemDecoration extends RecyclerView.ItemDecoration {

    private Context ctx;

    public OffsetItemDecoration(Context ctx){
        this.ctx = ctx;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        int nCols = ActivityUtils.getNumCols(ctx);
        int colWidth = (int)(getScreenWidth()/(float)(nCols));

        if(parent.getChildAdapterPosition(view) == 0){
            int offset = Math.round(getScreenWidth() / 2f - colWidth / 2f);
            setupOutRect(outRect, offset, true);
        }

        else if (parent.getChildAdapterPosition(view) == state.getItemCount()-1){
            int offset = Math.round(getScreenWidth() / 2f - colWidth / 2f);
            setupOutRect(outRect, offset, false);
        }
    }

    private void setupOutRect(Rect rect, int offset, boolean start){
        if(start) rect.left = offset;
        else rect.right = offset;
    }

    private  int getScreenWidth(){
        WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size.x;
    }
}

问题是,当RecyclerView 第一次填充时,第一项在屏幕中居中并且也被选中,但是当我尝试水平滚动并返回第一项时,最左边的项我可以选择的是第二个(位置1)。最后一个项目也是如此,可以捕捉到的最右边的项目是倒数第二个项目。 (state.getItemCount() - 2)。

我需要实现一个新的SnapHelper 还是我做错了什么?

【问题讨论】:

  • 那是因为 listView 的长度。第一项和最后一项不可访问。我有一个类似的问题,只是添加了默认的不可见项目来补偿不可到达的区域。但是,为此,您需要针对不同的屏幕尺寸进行一些计算。但这只是一种 hacky-wacky 的解决方案,也许(我希望如此)有更好的解决方案..
  • @Opiatefuchs 从理论上讲,我的ItemDecoration 添加的人为偏移量应该会阻止我创建此类虚拟项目。
  • 是的....理论上....我在偏移方面没有任何成功。但这不是为我的需要而设计的。我的目标是有一个水平的 recyclerView 让项目从左到右(反之亦然)滑动到屏幕末端。偏移量会切割边缘,并且项目直到屏幕结束才会滚动。由于这个问题,我决定添加一些不可见的视图,直到找到另一个解决方案。

标签: android android-layout android-recyclerview


【解决方案1】:

RecyclerViewItemDecoration 有自己的规则。他认为它们是物品本身的一部分。你可以想,你的decoration(即使它只是一个padding)是你my_item.xml本身的一部分。

LinearSnapHelper 使用类似LayoutManager.getDecoratedMeasuredWidth() 的方法来确定视图的中心。这就是问题发生的地方。它看到你的第一个项目比你想象的要大得多,所以它的第一个视图的中心实际上是在(padding + view.getWidth()) / 2。第二个视图比中心远得多,这是正常的view.getX() + view.getWidth() / 2

【讨论】:

    猜你喜欢
    • 2019-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多