• RecyclerView滑动到指定位置


    转:https://www.dazhuanlan.com/2019/12/16/5df6e27c71058/?__cf_chl_jschl_tk__=45b506af0a5845c229f6bcff22c07e3a50fbcabf-1609382170-0-AX6zhXvb63rOcwTNx--VLk8gWlC7KLxJkxoJdhyzcFpu2qKoP5D-4E7Ifwm2q_frwWyoZz2Tc8K2oyBtZ6sqlllnkw4C6BqmQBUKz8nVVrLNRryyAQtMa8N1dw1AvS9F7vrLz8XexzGHXccl-eiFfEu9E7n26HIPwl67cCq-W2jdrhwR-ZO392s5oQod9EO1KeiwurDvsyrJJiTbq7eBZ7MGKk5sLXicXfav_alHx_EM_2rU61WAuxYRBAGgjjwV0bcuElklPvcLTrNYZNDMgvmhVGRnVxgS8cekVmATdZkTjTEqEwObgAktShJxTfSHp-4xWWKMWgTyf8qgAJYd-7Y

    前言

    有个项目,需要定位recyclerView到某个item。
    一般用 mRecycleview.smoothScrollToPosition(0) 滑动到顶部,具有滚动效果。
    但是如果我们想滚动到任意指定位置,那么smoothScrollToPosition()
    就不能保证所指定item位于屏幕顶部,以下参照网上的一些帖子做一下收藏整合:

    第一种

    能实现指定位置位于屏幕顶部,但是不具有平滑滚动视觉效果

    1
    2
    3
    4
    5
    if (position != -1) {
    mRecycleview.scrollToPosition(position);
    LinearLayoutManager mLayoutManager = (LinearLayoutManager) mRecycleview.getLayoutManager();
    mLayoutManager.scrollToPositionWithOffset(position, 0);
    }

    第二种

    能实现指定位置位于屏幕顶部,具有平滑滚动视觉效果

    1. 如果如果跳转位置在第一个可见位置之前,就smoothScrollToPosition()可以直接跳转;
    2. 如果跳转位置在第一个可见项之后,最后一个可见项之前smoothScrollToPosition()不会滚动,调用smoothScrollBy来滑动到指定位置;
    3. 如果要跳转的位置在最后可见项之后,则先调用smoothScrollToPosition()将要跳转的位置滚动到可见位置,在addOnScrollListener()里通过onScrollStateChanged控制,调用smoothMoveToPosition,再次执行判断;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    private boolean mShouldScroll;  

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

    if (position < firstItem) {
    // 第一种可能:跳转位置在第一个可见位置之前
    mRecyclerView.smoothScrollToPosition(position);
    } else if (position <= lastItem) {
    // 第二种可能:跳转位置在第一个可见位置之后
    int movePosition = position - firstItem;
    if (movePosition >= 0 && movePosition < mRecyclerView.getChildCount()) {
    int top = mRecyclerView.getChildAt(movePosition).getTop();
    mRecyclerView.smoothScrollBy(0, top);
    }
    } else {
    // 第三种可能:跳转位置在最后可见项之后
    mRecyclerView.smoothScrollToPosition(position);
    mToPosition = position;
    mShouldScroll = true;
    }
    }

    //在onCreate中设置滚动监听事件
    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);
    if (mShouldScroll&& RecyclerView.SCROLL_STATE_IDLE == newState) {
    mShouldScroll = false;
    smoothMoveToPosition(irc, mToPosition);
    }
    }
    });

    //最后在具体业务中,设置
    if (position != -1) {
    smoothMoveToPosition(irc,position);
    }else {
    smoothMoveToPosition(irc,position+1);
    }

    特殊情况

    另一种简单粗暴的方案:项目里有要求滚动到不可视的item,而在recycler是有Holder机制,没有显示不加载,需要先滚动到相对应的holder,等在加载完所有的holder之后,在通过adapter设置item的内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //具体业务,
    recyclerView.scrollToPosition(curPosition);
    LinearLayoutManager mLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
    mLayoutManager.scrollToPositionWithOffset(curPosition, 0);

    // 延迟一秒,原因:在recycler的Holder机制
    new Handler().postDelayed(new Runnable() {

    public void run() {
    adapter.setLocation(curPosition);
    }
    }, 1000);

    参考链接

    1. RecyclerView滑动到指定位置,并指定位置在顶部
  • 相关阅读:
    Linux中的MyEclipse配置Hadoop
    C#学习笔记(三)
    关于读博,关于成为一个专家
    C#查找子串在原串中出现次数
    C#学习笔记(二)
    Matlab中sortrows函数解析
    C#学习笔记(一)
    甘特图与网络图
    ubuntu开启SSH服务
    分词错误重点分析这几项
  • 原文地址:https://www.cnblogs.com/CipherLab/p/14215149.html
Copyright © 2020-2023  润新知