LinearSnapHelper不能捕捉RecyclerView的边缘项目 [英] LinearSnapHelper doesn't snap on edge items of RecyclerView

查看:235
本文介绍了LinearSnapHelper不能捕捉RecyclerView的边缘项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我上一个问题的后续内容..

This is a follow-up to my previous question.

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

In my app I'm trying to have an horizontal RecyclerView that automatically snaps to the center item. To do so, I've attached a LinearSnapHelper to it. I've also created an item decoration that adds some left/right padding to the first/last element:

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).

The problem is that when the RecyclerView is populated the first time, the first item is centered in the screen and also selected, but when I try to horizontally scroll and I go back to the first item, the leftmost item I can select is the 2nd one (position 1). The same happens for the last item, the rightmost item that can be snapped to is the penultimate one. (state.getItemCount() - 2).

我是否需要实施新的SnapHelper还是做错了什么?

Do I need to implement a new SnapHelper or am I doing something wrong?

推荐答案

RecyclerView具有关于ItemDecoration的规则.他将它们视为项目本身的一部分.您可以认为,decoration(即使只是padding)是您my_item.xml本身的一部分.

RecyclerView has own rules about ItemDecoration. He thinks about them as a part of the item itself. You can think, what your decoration (even if it's just a padding) is part of your my_item.xml itself.

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

LinearSnapHelper uses methods like LayoutManager.getDecoratedMeasuredWidth() to determine center of the view. And that's from where the problem occurs. It sees your first item much larger than you think, so it's center for the first view is acutally in (padding + view.getWidth()) / 2. It is much farther than center for the second view, which is normal view.getX() + view.getWidth() / 2.

这篇关于LinearSnapHelper不能捕捉RecyclerView的边缘项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆