惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
N
Netflix TechBlog - Medium
GbyAI
GbyAI
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
T
Tailwind CSS Blog
IT之家
IT之家
博客园 - Franky
雷峰网
雷峰网
博客园 - 聂微东
腾讯CDC
M
MIT News - Artificial intelligence
B
Blog RSS Feed
博客园_首页
罗磊的独立博客
S
SegmentFault 最新的问题
I
InfoQ
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
D
Docker
宝玉的分享
宝玉的分享
B
Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

CAYZLH

Reasonix 开箱:聊聊我装的那些 Skill 收藏一份自驾中国的愿望清单 白夜行·谢幕 英雄联盟的昨日今天与符文大乱斗 折腾的尽头是极简 一个 `data.` 引发的血案——Redis 连接 localhost 问题排查全记录 MacBook上备忘录APP的快捷键和手势 让Google屏蔽某些搜索结果 WSL自定义安装Ubuntu typora自动上传图片配置 自建giscus服务 Windows下结束指定端口的进程 批量修改maven多模块版本号 使用winsw部署SpringBoot项目 Gson简易指南 docker搭建Consul集群 使用Docker部署SpringBoot项目 Docker使用redis镜像 Docker使用rabbitmq Docker使用zookeeper Docker使用MySQL Dockerfile常用指令 Docker免sudo操作 雷鸟电视去广告 使用ADB卸载MIUI系统应用 利用GitHub做图床 将网站变成灰色 Github上传大文件 Android远程调试命令adb vscode快捷键的使用
RecyclerView使用记录
Ant丶 · 2021-09-17 · via CAYZLH

随着公司自用app客户端功能&需求越来越复杂,某些页面的布局也越来越复杂。在前同事的建议下,使用RecyclerView来实现。

需求

大概需求如下图,需要通过登录用户的权限来展示这个表格布局。

IMG_0226

方案

  • 请求服务端登录接口,返回用户信息、角色信息、权限等
  • APP端根据权限组装数据传到Adapter
  • 渲染视图

实现

  • 在主页布局适合的布局添加以下布局代码

    <androidx.recyclerview.widget.RecyclerView
    android:id="@+id/workbench_recycleview"
    android:divider="#00000000"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/shape_bg"
    android:layout_marginLeft="15dp"
    android:layout_marginRight="15dp"
    android:layout_marginBottom="15dp">
    </androidx.recyclerview.widget.RecyclerView>
  • 定义item布局,代表每个item的布局样式等

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center_vertical"
    android:layout_marginTop="25dp"
    android:layout_marginLeft="15dp"
    android:layout_marginRight="15dp">

    <TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:text="标题"
    android:id="@+id/wb_menu_txt_title"
    android:textSize="16sp"
    android:textStyle="bold"
    android:textColor="#555555"/>

    <ImageView
    android:layout_width="36dp"
    android:layout_height="36dp"
    android:id="@+id/wb_menu_img_title"
    android:src="@mipmap/wk_ck"/>
    </LinearLayout>

    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="20dp"
    android:orientation="vertical"
    android:layout_marginBottom="25dp"
    android:layout_marginLeft="15dp"
    android:layout_marginRight="15dp">

    <TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="这是一段说明"
    android:id="@+id/wb_menu_txt_info"
    android:textSize="14sp"
    android:textColor="#999999"/>
    </LinearLayout>

    </LinearLayout>

    预览效果如下

    image-20210917204125464

  • 定义Holder类,继承RecyclerView.ViewHolder

    public class WorkBenchItemViewHolder extends RecyclerView.ViewHolder {

    private final TextView txtTitle;
    private final TextView txtInfo;
    private final ImageView imgTitle;

    public WorkBenchItemViewHolder(View view){
    super(view);
    txtTitle = view.findViewById(R.id.wb_menu_txt_title);
    txtInfo = view.findViewById(R.id.wb_menu_txt_info);
    imgTitle = view.findViewById(R.id.wb_menu_img_title);
    }

    public TextView getTxtInfo(){
    return this.txtInfo;
    }

    public ImageView getImg(){
    return this.imgTitle;
    }

    public TextView getTxtTitle(){
    return txtTitle;
    }
    }

  • 定义Adapter类,继承RecyclerView.Adapter<WorkBenchItemViewHolder>

    public class WorkBenchItemViewAdapter extends RecyclerView.Adapter<WorkBenchItemViewHolder> {

    public List<WorkbenchMenuBean> mDatas;
    private final Context mContext;
    private OnItemClickListener listener;

    public WorkBenchItemViewAdapter(Context context, List<WorkbenchMenuBean> datas) {
    this.mContext = context;
    this.mDatas = datas;
    }

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

    @Override
    public void onBindViewHolder(WorkBenchItemViewHolder holder, final int position) {
    holder.getTxtTitle().setText(mDatas.get(position).getTxtTitle());
    holder.getTxtInfo().setText(mDatas.get(position).getTxtInfo());
    holder.getImg().setImageResource(mDatas.get(position).getImgTitle());

    if (listener != null) {
    holder.itemView.setOnClickListener(view -> listener.onItemClick(view, position));
    }
    }

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


    public void setOnItemClickListener(OnItemClickListener listener) {
    this.listener = listener;
    }

    public interface OnItemClickListener {
    void onItemClick(View view, int position);
    }

    }
  • 在对应的页面初始化页面逻辑处添加处理逻辑

    定义相关属性

    private RecyclerView recyclerView;
    private WorkBenchItemViewAdapter adapter;
    private List<WorkbenchMenuBean> listData = new ArrayList<>();

    定义获取列表的方法




    boolean superAccount = loginInfo.isSuperAccount();
    if (superAccount) {
    listData.add(new WorkbenchMenuBean("pb", "功能1", "功能1描述", R.mipmap.wk_pb));
    listData.add(new WorkbenchMenuBean("zj", "功能2", "。。。", R.mipmap.wk_zj));
    listData.add(new WorkbenchMenuBean("sc", "功能3", "。。。", R.mipmap.wk_sc));
    listData.add(new WorkbenchMenuBean("ck", "功能4", "。。。", R.mipmap.wk_ck));
    listData.add(new WorkbenchMenuBean("sk", "功能5", "。。。", R.mipmap.wk_sk));
    return;
    }

    这里更好的处理方法是这些data也通过服务端返回,客户端只管处理

    调用recyclerView的其他api


    recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
    recyclerView.addItemDecoration(new CommonDecoration(Objects.requireNonNull(getContext())));

    adapter = new WorkBenchItemViewAdapter(getContext(), listData);


    adapter.setOnItemClickListener((view, position) -> {
    WorkbenchMenuBean workbenchMenuBean = adapter.mDatas.get(position);
    onWorkbenchMenuItemClick(workbenchMenuBean);
    });
    recyclerView.setAdapter(adapter);

常用方法

1、获取recyclerView内容高度


int recyclerViewRealHeight = recyclerView.computeVerticalScrollRange();

我们通过recyclerView.getHeight方法获取到的高度是RecyclerView控件的高度,不是内容高度

2、获取adapter中的item总个数

int size = recyclerView.getAdapter().getItemCount();

3、获取recyclerView可见的item数量

int childCount = recyclerView.getChildCount();

4、获取某个Item的实际position

RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

int position = params.getViewLayoutPosition();


int position = recyclerView.getChildAdapterPosition(view);

5、根据position获取对应的Item的View,需要注意的是,如果当前position对应的View不可见,获取到的View为null。


View itemView = llm.findViewByPosition(position);

6、获取第一个可见的Item的position

int firstPosition = ((LinearLayoutManager)recyclerView.getLayoutManager()).findFirstVisibleItemPosition();


View childFirst = recyclerView.getChildAt(0);
RecyclerView.LayoutParams paramsFirst = (RecyclerView.LayoutParams) childFirst.getLayoutParams();
int firstPosition1 = paramsFirst.getViewLayoutPosition();

7、获取第一个完全可见的Item的position

int firstCompletelyVisibleItemPosition = ((LinearLayoutManager)recyclerView.getLayoutManager()).findFirstCompletelyVisibleItemPosition();

8、获取最后一个可见的Item的position

int lastPosition = ((LinearLayoutManager)recyclerView.getLayoutManager()).findLastVisibleItemPosition();


int childCount = recyclerView.getChildCount();
View childLast = recyclerView.getChildAt(childCount - 1);
RecyclerView.LayoutParams paramsLast = (RecyclerView.LayoutParams) childLast.getLayoutParams();
int lastPosition1 = paramsLast.getViewLayoutPosition();

9、获取最后一个完全可见的Item的position

int lastCompletelyVisibleItemPosition = ((LinearLayoutManager)parent.getLayoutManager()