RecyclerView跳转到指定位置

自从android5.0推出RecyclerView以后,RecyclerView越来越受广大程序员的热爱了!大家都知道RecyclerView的出现目的是为了替代listview和ScrollView在列表方面的使用!那么listview和ScrollView的所有功能和方法都应该有的!

但是RecyclerView的很多方法,不是封装在RecyclerView中的,当我们在RecyclerView中找不到对应的方法时,就应该想到他的管理类manager了!
大多方法都封装在此啊!

最近有个同学用到了RecyclerView跳转到指定位置的需求,其实很简单,在这里我就给出我的做法,有指教的和改进的欢迎提出,需要用的就用,勿喷哈…..

方法一,直接使用当前的manager(类似于支付宝 更多里面的交互)

  /**
     * RecyclerView 移动到当前位置,
     *
     * @param manager  设置RecyclerView对应的manager
     * @param n  要跳转的位置
     */
    public static void MoveToPosition(LinearLayoutManager manager, int n) {
        manager.scrollToPositionWithOffset(n, 0);
        manager.setStackFromEnd(true);
    }

方法二、根据当前RecyclerView的条目数量,这个相对复杂一些,但是可以有效地避免指针越界呦..

/**
 * RecyclerView 移动到当前位置,
 *
 * @param manager   设置RecyclerView对应的manager
 * @param mRecyclerView  当前的RecyclerView
 * @param n  要跳转的位置
 */
public static void MoveToPosition(LinearLayoutManager manager, RecyclerView mRecyclerView, int n) {


    int firstItem = manager.findFirstVisibleItemPosition();
    int lastItem = manager.findLastVisibleItemPosition();
    if (n <= firstItem) {
        mRecyclerView.scrollToPosition(n);
    } else if (n <= lastItem) {
        int top = mRecyclerView.getChildAt(n - firstItem).getTop();
        mRecyclerView.scrollBy(0, top);
    } else {
        mRecyclerView.scrollToPosition(n);
    }

}

方法三:带有滚动效果

  /**
     * 目标项是否在最后一个可见项之后
     */
    private boolean mShouldScroll;
    /**
     * 记录目标项位置
     */
    private int mToPosition;

    /**
     * 滑动到指定位置
     *
     * @param mRecyclerView
     * @param position
     */
    private void smoothMoveToPosition(RecyclerView mRecyclerView, final int position) {
        // 第一个可见位置
        int firstItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(0));
        // 最后一个可见位置
        int lastItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(mRecyclerView.getChildCount() - 1));

        if (position < firstItem) {
            // 如果跳转位置在第一个可见位置之前,就smoothScrollToPosition可以直接跳转
            mRecyclerView.smoothScrollToPosition(position);
        } else if (position <= lastItem) {
            // 跳转位置在第一个可见项之后,最后一个可见项之前
            // smoothScrollToPosition根本不会动,此时调用smoothScrollBy来滑动到指定位置
            int movePosition = position - firstItem;
            if (movePosition >= 0 && movePosition < mRecyclerView.getChildCount()) {
                int top = mRecyclerView.getChildAt(movePosition).getTop();
                mRecyclerView.smoothScrollBy(0, top);
            }
        } else {
            // 如果要跳转的位置在最后可见项之后,则先调用smoothScrollToPosition将要跳转的位置滚动到可见位置
            // 再通过onScrollStateChanged控制再次调用smoothMoveToPosition,执行上一个判断中的方法
            mRecyclerView.smoothScrollToPosition(position);
            mToPosition = position;
            mShouldScroll = true;
        }
    }
 mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (mShouldScroll) {
                    mShouldScroll = false;
                    smoothMoveToPosition(mRecyclerView, mToPosition);
                }
            }
        });

好了这样就可以了,不信你试试…….

### 实现RecyclerView Item点击事件 为了实现在Android中通过RecyclerView项点击启动新的Activity或Fragment功能,可以采用自定义接口的方式。这种方法不仅灵活而且易于维护。 #### 自定义接口方式 创建一个接口`ItemClickListener.java`用于传递点击事件: ```java public interface ItemClickListener { void onItemClick(int position); } ``` 在适配器类中声明该接口实例,并提供setter方法以便外部组件传入监听器对象: ```java private ItemClickListener mListener; // setter method to set listener object from outside of adapter class. public void setOnItemClickListener(ItemClickListener listener){ this.mListener = listener; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout,parent,false); final ViewHolder holder = new ViewHolder(view,mListener); // Pass the click listener into ViewHolder constructor. return holder; } ``` 更新ViewHolder构造函数接收并绑定点击事件处理器: ```java class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private ItemClickListener clickListener; public ViewHolder(View itemView ,ItemClickListener listener) { super(itemView); this.clickListener=listener; itemView.setOnClickListener(this); } @Override public void onClick(View v) { if (clickListener != null) { clickListener.onItemClick(getAdapterPosition()); } } } ``` 最后,在Activity或Fragment里设置具体的响应逻辑: 对于Activity来说, ```java recyclerView.setAdapter(adapter); adapter.setOnItemClickListener(new ItemClickListener() { @Override public void onItemClick(int position) { Intent intent=new Intent(CurrentActivity.this,DestinationActivity.class); startActivity(intent); } }); ``` 如果是Fragment,则应这样操作, ```java recyclerView.setAdapter(adapter); adapter.setOnItemClickListener(position -> getParentFragmentManager().beginTransaction() .replace(R.id.fragment_container,new DestinationFragment()) .addToBackStack(null).commit()); ``` 上述代码展示了如何利用自定义接口机制来处理RecyclerView item的点击事件[^1]。此方案解决了直接在XML布局文件内指定onClick属性所带来的局限性[^2]。当面对更复杂的场景比如列表嵌套时,也可以基于相同原理进一步扩展解决方案[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值