使用RecyclerView实现左右并排分类选择

2023-10-29 17:32

本文主要是介绍使用RecyclerView实现左右并排分类选择,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家在做项目时肯定都会使用到RecyclerView来显示列表数据,今天实现一个左右并排的效果。
在这里插入图片描述
用到的依赖库如下

 implementation 'com.squareup.retrofit2:retrofit:2.9.0'implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

界面中用到的Api接口来自于玩Android,同时感谢鸿洋大大的分享。
接口地址 我这里用的是体系数据相关的Api
接着是布局,xml中是一个线性布局,放置了一个TextView用来显示标题的,下面是两个RecyclerView 分别用来显示左侧内容和右侧内容。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".activity.KnowledgeActivity"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="40dp"android:background="@color/colorPrimary"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_centerVertical="true"android:layout_marginLeft="12dp"android:text="知识体系"android:textSize="15sp"android:textColor="@color/white"/></RelativeLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"android:background="@color/white"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rv_left_view"android:layout_width="120dp"android:layout_height="match_parent"android:overScrollMode="never"></androidx.recyclerview.widget.RecyclerView><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rv_right_view"android:layout_width="match_parent"android:layout_height="match_parent"android:overScrollMode="never"></androidx.recyclerview.widget.RecyclerView></LinearLayout></LinearLayout>

接下来在项目中定义一个接口用来存放请求的Url

package com.ranlegeran.aroutertest.api;import com.ranlegeran.aroutertest.bean.Knowledge;
import com.ranlegeran.aroutertest.bean.KnowledgeArticle;
import com.ranlegeran.aroutertest.bean.ProjectTree;import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Url;public interface ApiService {//体系数据@GET("tree/json")Call<Knowledge> getKnowledge();//知识体系下的文章@GET()Call<KnowledgeArticle> getKnowledgeArticle(@Url String url);}

Knowledge类和KnowledgeArticle类的实体

package com.ranlegeran.aroutertest.bean;import java.io.Serializable;
import java.util.List;public class Knowledge {private int errorCode;private String errorMsg;private List<DataBean> data;public int getErrorCode() {return errorCode;}public void setErrorCode(int errorCode) {this.errorCode = errorCode;}public String getErrorMsg() {return errorMsg;}public void setErrorMsg(String errorMsg) {this.errorMsg = errorMsg;}public List<DataBean> getData() {return data;}public void setData(List<DataBean> data) {this.data = data;}public static class DataBean {private int courseId;private int id;private String name;private int order;private int parentChapterId;private boolean userControlSetTop;private int visible;private List<ChildrenBean> children;public int getCourseId() {return courseId;}public void setCourseId(int courseId) {this.courseId = courseId;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getOrder() {return order;}public void setOrder(int order) {this.order = order;}public int getParentChapterId() {return parentChapterId;}public void setParentChapterId(int parentChapterId) {this.parentChapterId = parentChapterId;}public boolean isUserControlSetTop() {return userControlSetTop;}public void setUserControlSetTop(boolean userControlSetTop) {this.userControlSetTop = userControlSetTop;}public int getVisible() {return visible;}public void setVisible(int visible) {this.visible = visible;}public List<ChildrenBean> getChildren() {return children;}public void setChildren(List<ChildrenBean> children) {this.children = children;}public static class ChildrenBean {private int courseId;private int id;private String name;private int order;private int parentChapterId;private boolean userControlSetTop;private int visible;private List<?> children;public int getCourseId() {return courseId;}public void setCourseId(int courseId) {this.courseId = courseId;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getOrder() {return order;}public void setOrder(int order) {this.order = order;}public int getParentChapterId() {return parentChapterId;}public void setParentChapterId(int parentChapterId) {this.parentChapterId = parentChapterId;}public boolean isUserControlSetTop() {return userControlSetTop;}public void setUserControlSetTop(boolean userControlSetTop) {this.userControlSetTop = userControlSetTop;}public int getVisible() {return visible;}public void setVisible(int visible) {this.visible = visible;}public List<?> getChildren() {return children;}public void setChildren(List<?> children) {this.children = children;}}}
}
package com.ranlegeran.aroutertest.bean;import java.io.Serializable;
import java.util.List;public class KnowledgeArticle {private DataBean data;private int errorCode;private String errorMsg;public DataBean getData() {return data;}public void setData(DataBean data) {this.data = data;}public int getErrorCode() {return errorCode;}public void setErrorCode(int errorCode) {this.errorCode = errorCode;}public String getErrorMsg() {return errorMsg;}public void setErrorMsg(String errorMsg) {this.errorMsg = errorMsg;}public static class DataBean {private int curPage;private int offset;private boolean over;private int pageCount;private int size;private int total;private List<DatasBean> datas;public int getCurPage() {return curPage;}public void setCurPage(int curPage) {this.curPage = curPage;}public int getOffset() {return offset;}public void setOffset(int offset) {this.offset = offset;}public boolean isOver() {return over;}public void setOver(boolean over) {this.over = over;}public int getPageCount() {return pageCount;}public void setPageCount(int pageCount) {this.pageCount = pageCount;}public int getSize() {return size;}public void setSize(int size) {this.size = size;}public int getTotal() {return total;}public void setTotal(int total) {this.total = total;}public List<DatasBean> getDatas() {return datas;}public void setDatas(List<DatasBean> datas) {this.datas = datas;}public static class DatasBean {private String apkLink;private int audit;private String author;private boolean canEdit;private int chapterId;private String chapterName;private boolean collect;private int courseId;private String desc;private String descMd;private String envelopePic;private boolean fresh;private String host;private int id;private String link;private String niceDate;private String niceShareDate;private String origin;private String prefix;private String projectLink;private long publishTime;private int realSuperChapterId;private int selfVisible;private long shareDate;private String shareUser;private int superChapterId;private String superChapterName;private String title;private int type;private int userId;private int visible;private int zan;private List<?> tags;public String getApkLink() {return apkLink;}public void setApkLink(String apkLink) {this.apkLink = apkLink;}public int getAudit() {return audit;}public void setAudit(int audit) {this.audit = audit;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public boolean isCanEdit() {return canEdit;}public void setCanEdit(boolean canEdit) {this.canEdit = canEdit;}public int getChapterId() {return chapterId;}public void setChapterId(int chapterId) {this.chapterId = chapterId;}public String getChapterName() {return chapterName;}public void setChapterName(String chapterName) {this.chapterName = chapterName;}public boolean isCollect() {return collect;}public void setCollect(boolean collect) {this.collect = collect;}public int getCourseId() {return courseId;}public void setCourseId(int courseId) {this.courseId = courseId;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}public String getDescMd() {return descMd;}public void setDescMd(String descMd) {this.descMd = descMd;}public String getEnvelopePic() {return envelopePic;}public void setEnvelopePic(String envelopePic) {this.envelopePic = envelopePic;}public boolean isFresh() {return fresh;}public void setFresh(boolean fresh) {this.fresh = fresh;}public String getHost() {return host;}public void setHost(String host) {this.host = host;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getLink() {return link;}public void setLink(String link) {this.link = link;}public String getNiceDate() {return niceDate;}public void setNiceDate(String niceDate) {this.niceDate = niceDate;}public String getNiceShareDate() {return niceShareDate;}public void setNiceShareDate(String niceShareDate) {this.niceShareDate = niceShareDate;}public String getOrigin() {return origin;}public void setOrigin(String origin) {this.origin = origin;}public String getPrefix() {return prefix;}public void setPrefix(String prefix) {this.prefix = prefix;}public String getProjectLink() {return projectLink;}public void setProjectLink(String projectLink) {this.projectLink = projectLink;}public long getPublishTime() {return publishTime;}public void setPublishTime(long publishTime) {this.publishTime = publishTime;}public int getRealSuperChapterId() {return realSuperChapterId;}public void setRealSuperChapterId(int realSuperChapterId) {this.realSuperChapterId = realSuperChapterId;}public int getSelfVisible() {return selfVisible;}public void setSelfVisible(int selfVisible) {this.selfVisible = selfVisible;}public long getShareDate() {return shareDate;}public void setShareDate(long shareDate) {this.shareDate = shareDate;}public String getShareUser() {return shareUser;}public void setShareUser(String shareUser) {this.shareUser = shareUser;}public int getSuperChapterId() {return superChapterId;}public void setSuperChapterId(int superChapterId) {this.superChapterId = superChapterId;}public String getSuperChapterName() {return superChapterName;}public void setSuperChapterName(String superChapterName) {this.superChapterName = superChapterName;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public int getType() {return type;}public void setType(int type) {this.type = type;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}public int getVisible() {return visible;}public void setVisible(int visible) {this.visible = visible;}public int getZan() {return zan;}public void setZan(int zan) {this.zan = zan;}public List<?> getTags() {return tags;}public void setTags(List<?> tags) {this.tags = tags;}}}
}

现在来编写左边RecyclerView的适配器

package com.ranlegeran.aroutertest.adapter;import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;import com.ranlegeran.aroutertest.R;
import com.ranlegeran.aroutertest.bean.Knowledge;import java.util.ArrayList;
import java.util.List;public class KnowledgeLeftAdapter extends RecyclerView.Adapter<KnowledgeLeftAdapter.ViewHolder> {private List<Knowledge.DataBean> mDataList = new ArrayList<>();//用来标记选中的位置private int mCurrentPosition = 0;//左侧Item的点击事件private OnLeftItemClickListener mOnItemClickListener = null;@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_knowledge_left, parent, false);return new ViewHolder(mView);}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {Knowledge.DataBean mDataBean = mDataList.get(position);holder.mTextName.setText(mDataBean.getName());if (mCurrentPosition == position) {//选中的背景颜色和字体颜色holder.mTextName.setBackgroundColor(Color.parseColor("#FFFFFF"));holder.mTextName.setTextColor(Color.parseColor("#FF402E"));} else {//未选中的背景颜色和字体颜色holder.mTextName.setBackgroundColor(Color.parseColor("#F2F3F8"));holder.mTextName.setTextColor(Color.parseColor("#333333"));}holder.itemView.setOnClickListener(v -> {if (mOnItemClickListener != null && mCurrentPosition != position) {mCurrentPosition = position;mOnItemClickListener.onLeftItemClick(mDataBean);notifyDataSetChanged();}});}@Overridepublic int getItemCount() {return mDataList.size();}//设置数据public void setData(Knowledge mKnowledge) {List<Knowledge.DataBean> mData = mKnowledge.getData();if (mData != null) {mDataList.clear();mDataList.addAll(mData);notifyDataSetChanged();}if (mDataList.size() > 0) {mOnItemClickListener.onLeftItemClick(mDataList.get(mCurrentPosition));}}class ViewHolder extends RecyclerView.ViewHolder {TextView mTextName;public ViewHolder(@NonNull View itemView) {super(itemView);mTextName = (TextView) itemView.findViewById(R.id.item_left_text_name);}}public void setOnLeftItemClickListener(OnLeftItemClickListener listener) {this.mOnItemClickListener = listener;}public interface OnLeftItemClickListener {void onLeftItemClick(Knowledge.DataBean item);}
}

左边item的布局文件,item_knowledge_left.xml 里面只放置了一个TextView用来显示文字。

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/item_left_text_name"android:layout_width="match_parent"android:layout_height="43dp"android:gravity="center"android:text="知识体系"android:textSize="15sp"></TextView>

右边的RecyclerView适配器

package com.ranlegeran.aroutertest.adapter;import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;import com.ranlegeran.aroutertest.R;
import com.ranlegeran.aroutertest.bean.KnowledgeArticle;
import java.util.ArrayList;
import java.util.List;public class RightContentAdapter extends RecyclerView.Adapter<RightContentAdapter.ViewHolder> {private List<KnowledgeArticle.DataBean.DatasBean> mDataList = new ArrayList<>();@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_right_content, parent, false);return new ViewHolder(mView);}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {KnowledgeArticle.DataBean.DatasBean mDataBean = mDataList.get(position);holder.mTextTitle.setText(mDataBean.getTitle());}@Overridepublic int getItemCount() {return mDataList.size();}//设置数据public void setData(KnowledgeArticle mKnowledgeArticle) {List<KnowledgeArticle.DataBean.DatasBean> mData = mKnowledgeArticle.getData().getDatas();mDataList.clear();mDataList.addAll(mData);notifyDataSetChanged();}class ViewHolder extends RecyclerView.ViewHolder {TextView mTextTitle;public ViewHolder(@NonNull View itemView) {super(itemView);mTextTitle = (TextView) itemView.findViewById(R.id.item_right_text_title);}}
}

右边的item布局,item_right_content 同样也只放置了一个TextView

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/item_right_text_title"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="15dp"android:textSize="13sp"></TextView>

最后KnowledgeActivity中的Java代码了

package com.ranlegeran.aroutertest.activity;import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;import android.os.Bundle;
import android.util.Log;import com.ranlegeran.aroutertest.R;
import com.ranlegeran.aroutertest.adapter.KnowledgeLeftAdapter;
import com.ranlegeran.aroutertest.adapter.RightContentAdapter;
import com.ranlegeran.aroutertest.api.ApiService;
import com.ranlegeran.aroutertest.bean.Knowledge;
import com.ranlegeran.aroutertest.bean.KnowledgeArticle;import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;public class KnowledgeActivity extends AppCompatActivity implements KnowledgeLeftAdapter.OnLeftItemClickListener {private static final String BASE_URL = "https://www.wanandroid.com/";private RecyclerView mRvLeftView;private RecyclerView mRvRightView;private KnowledgeLeftAdapter mLeftAdapter;private RightContentAdapter mRightAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_knowledge);initView();}private void initView() {mRvLeftView = (RecyclerView) findViewById(R.id.rv_left_view);mRvRightView = (RecyclerView) findViewById(R.id.rv_right_view);//左侧列表mRvLeftView.setLayoutManager(new LinearLayoutManager(this));mLeftAdapter = new KnowledgeLeftAdapter();mRvLeftView.setAdapter(mLeftAdapter);mLeftAdapter.setOnLeftItemClickListener(this);//右侧列表mRvRightView.setLayoutManager(new LinearLayoutManager(this));mRightAdapter = new RightContentAdapter();mRvRightView.setAdapter(mRightAdapter);//请求接口getKnowledge();}private void getKnowledge() {Retrofit mRetrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();ApiService mApi = mRetrofit.create(ApiService.class);Call<Knowledge> mCall = mApi.getKnowledge();mCall.enqueue(new Callback<Knowledge>() {@Overridepublic void onResponse(Call<Knowledge> call, Response<Knowledge> response) {Knowledge mKnowledge = response.body();//设置左边Adapter的数据mLeftAdapter.setData(mKnowledge);}@Overridepublic void onFailure(Call<Knowledge> call, Throwable t) {}});}@Overridepublic void onLeftItemClick(Knowledge.DataBean item) {int articleId = item.getId();int page = 0;String targetUrl = "article/list/" + page + "/json?" + "cid=" + articleId;Log.e("TAG", "Url: >>> " + targetUrl);Retrofit mRetrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();ApiService mApi = mRetrofit.create(ApiService.class);Call<KnowledgeArticle> mCall = mApi.getKnowledgeArticle(targetUrl);mCall.enqueue(new Callback<KnowledgeArticle>() {@Overridepublic void onResponse(Call<KnowledgeArticle> call, Response<KnowledgeArticle> response) {KnowledgeArticle mKnowledgeArticle = response.body();//设置右边Adapter的数据mRightAdapter.setData(mKnowledgeArticle);mRvRightView.scrollToPosition(0);}@Overridepublic void onFailure(Call<KnowledgeArticle> call, Throwable t) {}});}
}

首先在initView方法中把两个RecyclerView的控件找到,然后给两个View都设置了一个LayoutManager,接着拿到咱们创建的KnowledgeLeftAdapter和RightContentAdapter绑定在了对应的RecyclerView上。
getKnowledge();方法就是请求网络数据的部分在Retrofit的onResponse中调用了mLeftAdapter.setData(mKnowledge);来给左边的Adapter设置数据。

onLeftItemClick是左边Item的点击事件,我们在点击的时候拿到对应的id,然后根据这个id去请求知识体系下的文章,请求成功后同样在onResponse中调用 mRightAdapter.setData(mKnowledgeArticle);给右边的Adapter设置数据
mRvRightView.scrollToPosition(0); 这个方法是在点击左边切换内容的时候,右边的列表内容可以置顶到顶部。

这篇关于使用RecyclerView实现左右并排分类选择的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/302226

相关文章

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

java实现延迟/超时/定时问题

《java实现延迟/超时/定时问题》:本文主要介绍java实现延迟/超时/定时问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java实现延迟/超时/定时java 每间隔5秒执行一次,一共执行5次然后结束scheduleAtFixedRate 和 schedu

Java Optional避免空指针异常的实现

《JavaOptional避免空指针异常的实现》空指针异常一直是困扰开发者的常见问题之一,本文主要介绍了JavaOptional避免空指针异常的实现,帮助开发者编写更健壮、可读性更高的代码,减少因... 目录一、Optional 概述二、Optional 的创建三、Optional 的常用方法四、Optio

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

在Android平台上实现消息推送功能

《在Android平台上实现消息推送功能》随着移动互联网应用的飞速发展,消息推送已成为移动应用中不可或缺的功能,在Android平台上,实现消息推送涉及到服务端的消息发送、客户端的消息接收、通知渠道(... 目录一、项目概述二、相关知识介绍2.1 消息推送的基本原理2.2 Firebase Cloud Me

Spring Boot项目中结合MyBatis实现MySQL的自动主从切换功能

《SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能》:本文主要介绍SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能,本文分步骤给大家介绍的... 目录原理解析1. mysql主从复制(Master-Slave Replication)2. 读写分离3.

Redis实现延迟任务的三种方法详解

《Redis实现延迟任务的三种方法详解》延迟任务(DelayedTask)是指在未来的某个时间点,执行相应的任务,本文为大家整理了三种常见的实现方法,感兴趣的小伙伴可以参考一下... 目录1.前言2.Redis如何实现延迟任务3.代码实现3.1. 过期键通知事件实现3.2. 使用ZSet实现延迟任务3.3

基于Python和MoviePy实现照片管理和视频合成工具

《基于Python和MoviePy实现照片管理和视频合成工具》在这篇博客中,我们将详细剖析一个基于Python的图形界面应用程序,该程序使用wxPython构建用户界面,并结合MoviePy、Pill... 目录引言项目概述代码结构分析1. 导入和依赖2. 主类:PhotoManager初始化方法:__in

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

springboot filter实现请求响应全链路拦截

《springbootfilter实现请求响应全链路拦截》这篇文章主要为大家详细介绍了SpringBoot如何结合Filter同时拦截请求和响应,从而实现​​日志采集自动化,感兴趣的小伙伴可以跟随小... 目录一、为什么你需要这个过滤器?​​​二、核心实现:一个Filter搞定双向数据流​​​​三、完整代码