简体   繁体   English

LinearSnapHelper不会捕捉RecyclerView的边缘项目

[英]LinearSnapHelper doesn't snap on edge items of RecyclerView

This is a follow-up to my previous question . 这是我上一个问题的后续行动。

In my app I'm trying to have an horizontal RecyclerView that automatically snaps to the center item. 在我的应用程序中,我正在尝试使用水平RecyclerView自动捕捉到中心项目。 To do so, I've attached a LinearSnapHelper to it. 为此,我附上了一个LinearSnapHelper 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;
    }
}

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 ). 问题是当第一次填充RecyclerView时,第一个项目在屏幕中居中并且也被选中,但是当我尝试水平滚动并返回到第一个项目时,我可以选择的最左边的项目是第二个一个(位置1 )。 The same happens for the last item, the rightmost item that can be snapped to is the penultimate one. 对于最后一个项目也是如此,可以捕捉到的最右边的项目是倒数第二个项目。 ( state.getItemCount() - 2 ). state.getItemCount() - 2 )。

Do I need to implement a new SnapHelper or am I doing something wrong? 我是否需要实施新的SnapHelper或者我做错了什么?

RecyclerView has own rules about ItemDecoration . RecyclerView有自己的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. 你可以想一想,你的decoration (即使它只是一个padding )是my_item.xml本身的一部分。

LinearSnapHelper uses methods like LayoutManager.getDecoratedMeasuredWidth() to determine center of the view. LinearSnapHelper使用LayoutManager.getDecoratedMeasuredWidth()LayoutManager.getDecoratedMeasuredWidth()来确定视图的中心。 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 . 它会看到你的第一个项目比你想象的要大得多,所以它的第一个视图的中心位于(padding + view.getWidth()) / 2 It is much farther than center for the second view, which is normal view.getX() + view.getWidth() / 2 . 它比第二个视图的中心远得多,这是普通的view.getX() + view.getWidth() / 2

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM