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

推荐订阅源

T
The Blog of Author Tim Ferriss
WordPress大学
WordPress大学
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
小众软件
小众软件
博客园_首页
Blog — PlanetScale
Blog — PlanetScale
B
Blog RSS Feed
Martin Fowler
Martin Fowler
M
MIT News - Artificial intelligence
博客园 - 三生石上(FineUI控件)
博客园 - 【当耐特】
N
News | PayPal Newsroom
K
Kaspersky official blog
大猫的无限游戏
大猫的无限游戏
人人都是产品经理
人人都是产品经理
N
Netflix TechBlog - Medium
B
Blog
Recorded Future
Recorded Future
U
Unit 42
J
Java Code Geeks
Security Latest
Security Latest
H
Hackread – Cybersecurity News, Data Breaches, AI and More
V
Vulnerabilities – Threatpost
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Scott Helme
Scott Helme
Apple Machine Learning Research
Apple Machine Learning Research
aimingoo的专栏
aimingoo的专栏
T
Threatpost
Last Week in AI
Last Week in AI
Know Your Adversary
Know Your Adversary
Project Zero
Project Zero
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cloudbric
Cloudbric
AWS News Blog
AWS News Blog
NISL@THU
NISL@THU
有赞技术团队
有赞技术团队
博客园 - 叶小钗
N
News and Events Feed by Topic
V
V2EX
T
Troy Hunt's Blog
月光博客
月光博客
博客园 - Franky
P
Proofpoint News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
C
Cisco Blogs
The Cloudflare Blog
T
Tor Project blog
Google Online Security Blog
Google Online Security Blog

CAYZLH

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快捷键的使用 SpringBoot文件上传异常处理 SpringBoot封装JedisUtils工具类 SpringBoot自动部署脚本 使用Spring读取文件的几种方式 Spring统一异常返回 利用Github做Maven私服 Redis常用指令 Maven常用指令 使用mysqldump导出数据 SpringBoot动态切换多数据源 Java8的日期处理实践 lambda表达式语法 Stream表达式语法 使用Optional优雅地判空 Android Support vs AndroidX 「Vue」Runtime-Complier和Runtime-only的区别 动态设置布局之LayoutInflater Redis分布式锁的几种方案 打造一个舒服的写作环境(Hexo) 深入了解与使用ThreadLocal Maven中dependencyManagement的作用 Redis配置认证密码 nginx简单配置示例 Linux(macOS)换源 Linux搭建Git服务器 Linux配置ssh使用公钥登录远程服务器 Linux下find与exec的使用 Linux排查Java问题工具单 Linux常用命令 MySql数据库优化细节 API签名验证方案 Java集合框架 Redis基础知识总结 Spring事务管理 Redis为什么这么快 SpringBoot实现Jwt单点登录 SpringBoot实现Redis分布式锁 Spring面向切面编程(知识梳理) SpringBoot异步请求和异步调用 Mybatis中用到的几种设计模式 Docker Swarm RocketMQ相关流程图/原理图 SonarQube的安装与使用 宝塔面板部署vue项目 Tomcat的三种接收请求处理方式 Docker知识扫盲 安装Jenkins并用于部署SpringBoot项目 Tomcat单机多实例部署 Maven中Scope的分类 Springboot集成Shiro(前后端分离) Linux搭建frp服务(内网穿透) Redis高逼格指令 Docker私有仓库的搭建与使用 Dockerfile使用介绍 Redis的使用场景 Docker的网络模式
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()