LinearSnapHelper doesn't snap on edge items of RecyclerView

限于喜欢 提交于 2019-12-22 05:40:41

问题


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. 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;
    }
}

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

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


回答1:


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



来源:https://stackoverflow.com/questions/44766186/linearsnaphelper-doesnt-snap-on-edge-items-of-recyclerview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!