LinearSnapHelper不会捕捉RecyclerView的边缘项目

Vek*_*r88 6 android android-layout android-recyclerview

这是我上一个问题的后续行动.

在我的应用程序中,我正在尝试使用水平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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Nex*_*xen 9

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

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