使用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">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@color/colorPrimary">

    <TextView
        android: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>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:background="@color/white">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_left_view"
        android:layout_width="120dp"
        android:layout_height="match_parent"
        android:overScrollMode="never">
    </androidx.recyclerview.widget.RecyclerView>

    <androidx.recyclerview.widget.RecyclerView
        android: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
    @Override
    public 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);
    }

    @Override
    public 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();
            }
        });
    }

    @Override
    public 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
    @Override
    public 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);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        KnowledgeArticle.DataBean.DatasBean mDataBean = mDataList.get(position);
        holder.mTextTitle.setText(mDataBean.getTitle());
    }

    @Override
    public 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;

    @Override
    protected 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>() {
            @Override
            public void onResponse(Call<Knowledge> call, Response<Knowledge> response) {
                Knowledge mKnowledge = response.body();
                //设置左边Adapter的数据
                mLeftAdapter.setData(mKnowledge);
            }

            @Override
            public void onFailure(Call<Knowledge> call, Throwable t) {

            }
        });
    }

    @Override
    public 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>() {
            @Override
            public void onResponse(Call<KnowledgeArticle> call, Response<KnowledgeArticle> response) {
                KnowledgeArticle mKnowledgeArticle = response.body();
                //设置右边Adapter的数据
                mRightAdapter.setData(mKnowledgeArticle);
                mRvRightView.scrollToPosition(0);
            }

            @Override
            public 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); 这个方法是在点击左边切换内容的时候,右边的列表内容可以置顶到顶部。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值