RecyclerView 滚动到子视图子视图的位置

问题描述 投票:0回答:1

我要滚动到图中的位置:

这是我的代码,但有 NullPointerException

public class ViewMenu extends LinearLayout {
    protected Handler mHandler;
    @BindView(R.id.recycler)
    protected RecyclerView mRecycler;
    //...

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        ButterKnife.bind(this);
        mHandler = new Handler();
        mRecycler.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
        //...
        Message msg=new Message();
        msg.what=1;
        Bundle bundle=new Bundle();
        bundle.putInt("targetPosition",3);//assume this is a valid position
        bundle.putInt("targetChild",2);//assume this is a valid child
        msg.setData(bundle);
        handler.sendMessage(msg);
    }
    class Handler extends android.os.Handler {
        @Override
        public void handleMessage(Message msg) {
            int targetPosition=msg.getData().getInt("targetPosition");
            int targetChild=msg.getData().getInt("targetChild");
            LinearLayoutManager layoutManager = (LinearLayoutManager) mRecycler.getLayoutManager();
            ViewGroup targetViewGroup = (ViewGroup) layoutManager.findViewByPosition(targetPosition);//targetViewGroup becomes null
            View targetView = targetViewGroup.getChildAt(targetChild);//NullPointerException
            layoutManager.scrollToPositionWithOffset(targetPosition, targetView.getLeft());
        }
    }
}

我认为问题在于,当 targetViewGroup 不可见时,findViewByPosition 返回 null。有人能找到更好的方法吗?

java android android-recyclerview handler linearlayoutmanager
1个回答
0
投票

最后我自己解决了。我猜原因是当您调用layoutManager.scrollToPositionWithOffset()方法时,滚动事件被发送到处理程序。在循环器收到消息之前,回收器视图不会进行真正的滚动。所以正确的方法是在调用scrollToPositionWithOffset()之后使用handler.post()。

LinearLayoutManager layoutManager = (LinearLayoutManager) mRecycler.getLayoutManager();
//scroll to make the target page visible
if (page < layoutManager.findFirstVisibleItemPosition())
    //if the target page is in left and invisible, post: scroll to show one pixel in the screen left
    layoutManager.scrollToPositionWithOffset(page + 1, 1);
else if (page > layoutManager.findLastVisibleItemPosition())
    //if the target page is in right and invisible, post: scroll to show one pixel in the screen right
    layoutManager.scrollToPositionWithOffset(page, mRecycler.getWidth() - mRecycler.getPaddingLeft() - mRecycler.getPaddingRight() - 1);
//post: scroll to candidate
getHandler().post(() -> {
    ViewGroup pageView = (ViewGroup) mRecycler.findViewHolderForAdapterPosition(page).itemView;
    View candView = pageView.getChildAt(cand);
        layoutManager.scrollToPositionWithOffset(page, left ? candView.getLeft() : candView.getRight());
});
© www.soinside.com 2019 - 2024. All rights reserved.