Android:RecyclerView跨行跨列的LayoutManager:Spannedgridlayoutmanager

前言: 

RecyclerView可以使用GridLayoutManager实现跨行,但是不能跨列;瀑布流布局可以跨列但是又不能跨行。原生自带的各个LayoutManager中并没有可以又跨行又能跨列的。网上搜寻了一番,找到了一个亲测可行好用的三方库:spannedgridlayoutmanager。

实现效果预览:

依赖库的地址:

GitHub:GitHub - jmartinesp/SpannedGridLayoutManager: Android RecyclerView.LayoutManager that resizes and reorders views based on SpanSize

gitee:SpannedGridLayoutManager: Android RecyclerView.LayoutManager that resizes and reorders views based on SpanSize (gitee.com)

使用:

1、添加依赖:

dependencies {implementation 'com.arasthel:spannedgridlayoutmanager:3.0.2'
}

如果依赖不成功或者想要自定义spannedgridlayoutmanager里面的代码,使用Module的方式来导入该项目。这边提供资源地址:spannedgridlayoutmanager-3.0.2资源-CSDN文库

2、代码中使用:

        recyclerView.setAdapter(adapter);//参数Orientation.VERTICAL表示列表竖向;4表示4列SpannedGridLayoutManager gridLayoutManager = new SpannedGridLayoutManager(SpannedGridLayoutManager.Orientation.VERTICAL, 4);gridLayoutManager.setSpanSizeLookup(new SpannedGridLayoutManager.SpanSizeLookup(position -> {int col = 1;int row = 1;switch (adapter.getItemViewType(position)) {case ITEM_TYPE_1x2:col = 2;break;case ITEM_TYPE_1x4:col = 4;break;case ITEM_TYPE_2x1:row = 2;break;case ITEM_TYPE_2x2:col = 2;row = 2;break;case ITEM_TYPE_1x1:default:break;}return new SpanSize(col, row);}));recyclerView.setLayoutManager(gridLayoutManager);

根据你每一项item所需要占的格子数大小设置所跨宽和列的单元格个数。

就可以啦。

完整代码:

这边代码包含了item拖动功能,详细解释和实现方式可以参考我另一篇博客:Android:RecyclerView自由拖动itemicon-default.png?t=N7T8http://t.csdnimg.cn/bPdbl不需要拖拽功能的忽略即可。

适配器:

public class AppsCardAdapter extends RecyclerView.Adapter<AppsCardAdapter.MyHolder> {private final List<Integer> mList;private final Context mContext;private final int ITEM_TYPE_1x1 = 0;private final int ITEM_TYPE_1x2 = 1;private final int ITEM_TYPE_1x4 = 2;private final int ITEM_TYPE_2x2 = 3;private final int ITEM_TYPE_2x1 = 4;AppsCardAdapter(Context context) {this.mContext = context;mList = new ArrayList<>();}@NonNull@Overridepublic MyHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int itemType) {View rootView = LayoutInflater.from(mContext).inflate(R.layout.item_apps_card, viewGroup, false);return new MyHolder(rootView);}@SuppressLint("SetTextI18n")@Overridepublic void onBindViewHolder(@NonNull MyHolder holder, int position) {int item = mList.get(position);holder.name.setText(item + "");holder.itemView.setOnClickListener(view -> {Toast.makeText(mContext, "item = "+item, Toast.LENGTH_SHORT).show();});}@Overridepublic int getItemCount() {return mList.size();}@Overridepublic int getItemViewType(int position) {TODO: 根据实际项目item的类型来,这边为了演示直接定死位置的类型了 switch (mList.get(position)){case 0:return ITEM_TYPE_1x4;case 1:case 4:case 6:return ITEM_TYPE_1x2;case 2:case 3:return ITEM_TYPE_2x1;case 5:return ITEM_TYPE_2x2;default:return ITEM_TYPE_1x1;}}static class MyHolder extends RecyclerView.ViewHolder {TextView name;public MyHolder(@NonNull  View itemView) {super(itemView);name = itemView.findViewById(R.id.name);}}//拖动功能的回调类private static class MyItemTouchHelperCallback extends ItemTouchHelper.Callback{private final AppsCardAdapter appsCardAdapter;public MyItemTouchHelperCallback(AppsCardAdapter appsCardAdapter) {this.appsCardAdapter = appsCardAdapter;}@Overridepublic int getMovementFlags(@NonNull  RecyclerView recyclerView,@NonNull  RecyclerView.ViewHolder viewHolder) {if (viewHolder.getItemViewType() == appsCardAdapter.ITEM_TYPE_1x4) {//不可拖动return makeMovementFlags(0, 0);}final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN| ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;return makeFlag(ItemTouchHelper.ACTION_STATE_DRAG, dragFlags);}@Overridepublic boolean onMove(@NonNull  RecyclerView recyclerView,@NonNull  RecyclerView.ViewHolder viewHolderSource,@NonNull  RecyclerView.ViewHolder viewHolderTarget) {if (viewHolderTarget.getItemViewType() == appsCardAdapter.ITEM_TYPE_1x4) {//不可拖动到这里return false;}appsCardAdapter.onMove(viewHolderSource.getAdapterPosition(),viewHolderTarget.getAdapterPosition());return true;}@Overridepublic void onSwiped(@NonNull  RecyclerView.ViewHolder viewHolder, int i) {}}private void onMove(int sourcePosition, int targetPosition) {int item = mList.get(sourcePosition);mList.remove(sourcePosition);mList.add(targetPosition, item);notifyItemMoved(sourcePosition, targetPosition);}public void setRecyclerView(RecyclerView recyclerView) {recyclerView.setAdapter(this);SpannedGridLayoutManager gridLayoutManager = new SpannedGridLayoutManager(SpannedGridLayoutManager.Orientation.VERTICAL, 4);gridLayoutManager.setSpanSizeLookup(new SpannedGridLayoutManager.SpanSizeLookup(position -> {int col = 1;int row = 1;switch (getItemViewType(position)) {case ITEM_TYPE_1x2:col = 2;break;case ITEM_TYPE_1x4:col = 4;break;case ITEM_TYPE_2x1:row = 2;break;case ITEM_TYPE_2x2:col = 2;row = 2;break;case ITEM_TYPE_1x1:default:break;}return new SpanSize(col, row);}));recyclerView.setLayoutManager(gridLayoutManager);ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new MyItemTouchHelperCallback(this));itemTouchHelper.attachToRecyclerView(recyclerView);}public void setNewData(List<Integer> list) {this.mList.clear();this.mList.addAll(list);notifyDataSetChanged();}
}

Activity中使用:

        AppsCardAdapter adapter = new AppsCardAdapter(getContext());adapter.setRecyclerView(recyclerView);//测试数据ArrayList<Integer> list = new ArrayList<>();for (int i = 0; i < 13; i++) {list.add(i);}adapter.setNewData(list);

完。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/663600.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DL/T1578-2021电力线路多旋翼无人机巡检系

DL/T1578-2021电力线路多旋翼无人机巡检系 DL/T 1578—2021标准的发布和实施对于架空电力线路的巡检工作具有里程碑式的意义。它不仅填补了多旋翼无人机巡检系统在行业标准方面的空白&#xff0c;还为电力行业提供了一套完整、科学的测试和评估方法。这将有助于提高架空电力线…

使用apifox创建一个Mock Server Api 接口

安装 下载 Apifox - API 文档、调试、Mock、测试一体化协作平台。拥有接口文档管理、接口调试、Mock、自动化测试等功能&#xff0c;接口开发、测试、联调效率&#xff0c;提升 10 倍。最好用的接口文档管理工具&#xff0c;接口自动化测试工具。 创建mock api项目中使用 创建项…

构建LLM辅助生物威胁制造预警系统 人类越发展获取的超能力越大,破坏力越大,威胁越大。我们需要什么样的预警系统?既克服威胁又具有超能力 安全基础

https://openai.com/research/building-an-early-warning-system-for-llm-aided-biological-threat-creation 人类越发展获取的超能力越大&#xff0c;破坏力就越大&#xff0c;威胁越大。 人工智能就是为了赋予人人都能有超能力&#xff0c;而一旦被恶意或无意使用又威胁到人…

生产问题排查系列——未知404状态接口请求

引言 我们的产品主打金融服务领域&#xff0c;以B端客户为我们的核心合作伙伴&#xff0c;然而&#xff0c;我们的服务最终将惠及C端消费者。在技术实现上&#xff0c;我们采用了公司自主研发的微服务框架&#xff0c;该框架基于SpringBoot&#xff0c;旨在提供高效、可靠的服…

vtkNIFTIImageReader读写方位以及原点信息

使用vtkNIFTIImageReader读取体数据为vtkImageData时只会携带spacing信息&#xff0c;方向和原点信息不会写入&#xff0c;需要获取QFormMatrix进行解析。 1、方向及原点读取 vtkSmartPointer<vtkNIFTIImageReader> niiReader vtkSmartPointer<vtkNIFTIImageReader&…

数据结构—基础知识:哈夫曼树

数据结构—基础知识&#xff1a;哈夫曼树 哈夫曼树的基本概念 哈夫曼&#xff08;Huffman&#xff09;树又称最优树&#xff0c;是一类带权路径长度最短的树&#xff0c;在实际中有广泛的用途。哈夫曼树的定义&#xff0c;涉及路径、路径长度、权等概念&#xff0c;下面先给出…

Vue学习之使用HBuilderX创建并使用vue3.0项目

Vue学习之使用HBuilderX创建并使用vue3.0项目 下文将简述如何使用HBuilderX创建并使用vue3.0项目&#xff0c;包含项目创建、目录介绍、如何引用组件、首页自定义设置。 1、创建vue3.0项目 具体操作之前章节已经阐述过不在冗余介绍&#xff0c;创建时选择vue3项目即可。vue2…

【C++】C++入门 — 指针空值nullptr

C入门 指针空值 指针空值 在良好的C/C编程习惯中&#xff0c;声明一个变量时最好给该变量一个合适的初始值&#xff0c;否则可能会出现 不可预料的错误&#xff0c;比如未初始化的指针。如果一个指针没有合法的指向&#xff0c;我们基本都是按照如下 方式对其进行初始化: voi…

数据解构+算法(第07篇):动态编程!黄袍加身!

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

Vue3 函数式弹窗优化

背景 前面文章介绍了如何使用 函数式弹窗&#xff0c;弹窗方式是挂载在了全局&#xff0c;使用了getCurrentInstance方法拿到了全局上下文&#xff0c;进而拿到挂载的dialog进行弹窗操作。getCurrentInstance现在已被官方Vue API隐藏&#xff0c;为内部使用函数&#xff0c;现…

20240202在Ubuntu20.04.6下配置环境变量之后让nvcc --version显示正常

20240202在Ubuntu20.04.6下配置环境变量之后让nvcc --version显示正常 2024/2/2 20:19 在Ubuntu20.04.6下编译whiper.cpp的显卡模式的时候&#xff0c;报告nvcc异常了&#xff01; 百度&#xff1a;nvcc -v nvidia-cuda-toolkit rootrootrootroot-X99-Turbo:~/whisper.cpp$ WH…

ARM架构可视化ROS消息方案部署

ARM架构可视化ROS消息方案部署 三种方案, 1. webviz 2. foxglove 3. rosviz 注: web要用firefox, chromimum用不了, 可能是因为取消了时间同步机制的原因 先说三种方案的优劣, webviz 延迟比较高, 但是部署相对简单, foxglove 部署比较费劲, 但是效果不错, 延迟低, 本文会尽…

常见的企业网络问题及SD-WAN解决方案

现在办公都离不开网络&#xff0c;网络问题的解决是企业高效办公的必要条件。目前SD-WAN组网是很多企业会选择的网络解决方案。那么SD-WAN好在哪&#xff1f;可以帮助企业解决哪些用网难题呢&#xff1f; 一.解决网络性能不佳问题 当您的WAN受到压力时&#xff0c;数据包开始下…

Swagger学习使用

swagger升级导致访问ui页面地址不一样 方式一 依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.3.RELEASE</version> </parent> <dependen…

FUXA远程命令执行漏洞(CVE-2023-33831)

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

C++弹球游戏:Jump Ball Game

一、下载压缩包 请查看网站C弹球游戏&#xff1a;Jump Ball Game并且下载&#xff0c;可以看到如下界面&#xff1a; 二、匹配图标 把压缩包解压了&#xff1a; 右键点击Jump Ball Game.lnk&#xff0c;点击“属性”它将会是我们要运行的文件。 点击“更改图标”&#xff0c;选…

集合问题(并查集)

本题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 题目&#xff1a; 样例1&#xff1a; 输入 4 5 9 2 3 4 5 输出 YES 0 0 1 1 样例2&#xff1a; 输入 3 3 4 1 2 4 输出 NO 思路&#xff1a; 这道题关键点在于。 当集合中有一个元素均存在于集合 A 和集合 B 的时…

嵌入式学习步骤

嵌入式行业是一个涉及广泛领域的行业&#xff0c;嵌入式、物联网、人工智能、智能与科学、电子信息工程、通信工程、自动化工程、测控、计算机科学等专业在嵌入式系统中使得软件和硬件的结合更加高效&#xff0c;适合从事嵌入式物联网开发。 嵌入式学习步骤总结如下&#xff1a…

将有逻辑关系的树形结构数组转换为扁平化的一维对象数组(包含PID、ID父子关系)(tree转换为List)

// 将有逻辑关系的树形结构数组转换为扁平化的一维对象数组 treeStructure2flatArray(arr) {let r [], r_ (ar, PID root) > ar.forEach(v > (v.children && (r_(v.children, v.ID), delete v.children), (v.PID PID, r.push(v))));r_(JSON.parse(JSON.strin…

2.2日总结

第一题&#xff1a;搭配购买 题解&#xff1a;一看就是很普通的01背包问题&#xff0c;但是和查并集一起考了&#xff0c;首先我们需要把每个有联系的链接起来&#xff0c;形成一个大背包&#xff0c;用来装他们的总金额和总价值&#xff0c;然后我们在看一个个的物品进行取或者…