IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> RecyclerView选中的item保持在视图中间 -> 正文阅读

[移动开发]RecyclerView选中的item保持在视图中间

前言

最近在做一个音乐列表,希望正在播放的歌曲始终在列表中居中显示,类似下面的样子。
在这里插入图片描述
切换上一曲下一曲时始终能保持当前的歌曲始终居中。RecyclerView有两个函数smoothScrollToPosition和scrollToPosition都能滚动到指定的位置,但是并不能保持居中,自己做位置记忆的话又很麻烦,自己尝试了半天没有好方法,最终参考了一位大佬的文章。

https://blog.csdn.net/iblade/article/details/90449089

自定义布局管理器

继承LinearLayoutManager,重新smoothScrollToPosition方法实现滚动到指定的position

public class CenterLayoutManager extends LinearLayoutManager {
    public CenterLayoutManager(Context context) {
        super(context);
    }

    public CenterLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    public CenterLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
        super.smoothScrollToPosition(recyclerView, state, position);
        RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }

    private static class CenterSmoothScroller extends LinearSmoothScroller{

        public CenterSmoothScroller(Context context) {
            super(context);
        }
		// 正是该方法实现居中显示
        @Override
        public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
            return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
        }
    }
}

接下来我们在Adapter中通过一个变量记录下当前正在播放的歌曲的位置,需要时滚动到该位置即可。

public class PinAdapter extends RecyclerView.Adapter<PinAdapter.ViewHolder>{
    private static final String TAG = "PinAdapter";

    private Context context;
    private List<String> mList;
	// 记录当前歌曲位置
    public int mPosition = 0;

    public PinAdapter(Context context, List<String> mList) {
        this.context = context;
        this.mList = mList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.simple_text_layout,parent,false));
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        if (position == mPosition){
            holder.textView.setTextColor(Color.GREEN);
        }else {
            holder.textView.setTextColor(Color.WHITE);
        }
        holder.textView.setText(mList.get(position));
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder{

        private TextView textView;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.tv_simple_text);
        }
    }
}

设置适配器和布局管理器

        pinAdapter = new PinAdapter(this,list);
        recyclerView.setLayoutManager(new CenterLayoutManager(this));
        recyclerView.setAdapter(pinAdapter);
        // 为了让每一个item完整显示
        PagerSnapHelper helper = new PagerSnapHelper();
        helper.attachToRecyclerView(recyclerView);

PagerSnapHelper类是为了辅助让每一首歌都完整显示,不出现因为RecyclerView滚动时显示部分的情况,这个类是原生的可以直接使用。我们点击上一曲下一曲时就可以进行滚动并刷新了

            recyclerView.smoothScrollToPosition(pinAdapter.mPosition);
            pinAdapter.notifyDataSetChanged();

监听RecyclerView滚动

滑动歌曲时,我们希望在停止滑动一段时间后能回到正在播放的歌曲的位置,这时我们可以通过Handler来实现,停止滚动后发送一个延迟信息,比如3s后如果该信息没有被取消那么就回到播放位置,开始滑动时取消该消息。首先给RecyclerView添加一个监听器

        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                // 停止滚动
                if (newState == RecyclerView.SCROLL_STATE_IDLE){
                    Message message = mHanler.obtainMessage(1);
                    mHanler.sendMessageDelayed(message,3000);
                }else {
                    mHanler.removeMessages(1);
                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
            }
        });

方法onScrollStateChanged是在RecyclerView停止滑动时被调用,一般来说有如下几种状态

//停止滚动
public static final int SCROLL_STATE_IDLE = 0;
 
//正在被外部拖拽,一般为用户正在用手指滚动
public static final int SCROLL_STATE_DRAGGING = 1;
 
//自动滚动开始
public static final int SCROLL_STATE_SETTLING = 2;

我们只需要在开始滚动时移除handler消息,停止滚动后创建消息即可。
onScrolled函数一般是用来计算滚动距离之类的,比如希望将RecyclerView和一个外部的滚动条联系起来,我们则可以通过该函数计算,dx是水平滚动的距离,dy是垂直滚动的距离,正负代表滚动的方向,比如dy>0时表示向上滚动,dy<0时表示向下滚动。还可以通过其他两个函数去计算它的总长度和偏移量。

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                // RecyclerView总长度
                int max = recyclerView.computeVerticalScrollRange();
                // 当前位置偏移量
                int offset = recyclerView.computeVerticalScrollOffset();
            }
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-05-08 08:15:26  更:2022-05-08 08:16:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 23:50:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码