平台搭建与拆除/许昌seo公司
调用 FlowAdapter 跟普通recyclerview一样使用
RecyclerView rvLayout = holder.getView(R.id.spe_tag_layout);
FlowAdapter rvAdapter = new FlowAdapter();
FlowLayoutManager flowLayoutManager = new FlowLayoutManager();
rvLayout.setLayoutManager(flowLayoutManager);
rvLayout.setAdapter(rvAdapter);
/*** date:2024/1/10* author:wsm* describe:一种流式布局的LayoutManager*/
public class FlowLayoutManager extends RecyclerView.LayoutManager {private static final String TAG = FlowLayoutManager.class.getSimpleName();final FlowLayoutManager self = this;protected int width, height;private int left, top, right;//最大容器的宽度private int usedMaxWidth;//竖直方向上的偏移量private int verticalScrollOffset = 0;public int getTotalHeight() {return totalHeight;}//计算显示的内容的高度protected int totalHeight = 0;private Row row = new Row();private List<Row> lineRows = new ArrayList<>();//保存所有的Item的上下左右的偏移量信息private SparseArray<Rect> allItemFrames = new SparseArray<>();public FlowLayoutManager() {//设置主动测量规则,适应recyclerView高度为wrap_contentsetAutoMeasureEnabled(true);}//每个item的定义public class Item {int useHeight;View view;public void setRect(Rect rect) {this.rect = rect;}Rect rect;public Item(int useHeight, View view, Rect rect) {this.useHeight = useHeight;this.view = view;this.rect = rect;}}//行信息的定义public class Row {public void setCuTop(float cuTop) {this.cuTop = cuTop;}public void setMaxHeight(float maxHeight) {this.maxHeight = maxHeight;}//每一行的头部坐标float cuTop;//每一行需要占据的最大高度float maxHeight;//每一行存储的itemList<Item> views = new ArrayList<>();public void addViews(Item view) {views.add(view);}}@Overridepublic RecyclerView.LayoutParams generateDefaultLayoutParams() {return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);}//该方法主要用来获取每一个item在屏幕上占据的位置@Overridepublic void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {Log.d(TAG, "onLayoutChildren");totalHeight = 0;int cuLineTop = top;//当前行使用的宽度int cuLineWidth = 0;int itemLeft;int itemTop;int maxHeightItem = 0;row = new Row();lineRows.clear();allItemFrames.clear();removeAllViews();if (getItemCount() == 0) {detachAndScrapAttachedViews(recycler);verticalScrollOffset = 0;return;}if (getChildCount() == 0 && state.isPreLayout()) {return;}//onLayoutChildren方法在RecyclerView 初始化时 会执行两遍detachAndScrapAttachedViews(recycler);if (getChildCount() == 0) {width = getWidth();height = getHeight();left = getPaddingLeft();right = getPaddingRight();top = getPaddingTop();usedMaxWidth = width - left - right;}for (int i = 0; i < getItemCount(); i++) {Log.d(TAG, "index:" + i);View childAt = recycler.getViewForPosition(i);if (View.GONE == childAt.getVisibility()) {continue;}measureChildWithMargins(childAt, 0, 0);int childWidth = getDecoratedMeasuredWidth(childAt);int childHeight = getDecoratedMeasuredHeight(childAt);int childUseWidth = childWidth;int childUseHeight = childHeight;//如果加上当前的item还小于最大的宽度的话if (cuLineWidth + childUseWidth <= usedMaxWidth) {itemLeft = left + cuLineWidth;itemTop = cuLineTop;Rect frame = allItemFrames.get(i);if (frame == null) {frame = new Rect();}frame.set(itemLeft, itemTop, itemLeft + childWidth, itemTop + childHeight);allItemFrames.put(i, frame);cuLineWidth += childUseWidth;maxHeightItem = Math.max(maxHeightItem, childUseHeight);row.addViews(new Item(childUseHeight, childAt, frame));row.setCuTop(cuLineTop);row.setMaxHeight(maxHeightItem);} else {//换行formatAboveRow();cuLineTop += maxHeightItem;totalHeight += maxHeightItem;itemTop = cuLineTop;itemLeft = left;Rect frame = allItemFrames.get(i);if (frame == null) {frame = new Rect();}frame.set(itemLeft, itemTop, itemLeft + childWidth, itemTop + childHeight);allItemFrames.put(i, frame);cuLineWidth = childUseWidth;maxHeightItem = childUseHeight;row.addViews(new Item(childUseHeight, childAt, frame));row.setCuTop(cuLineTop);row.setMaxHeight(maxHeightItem);}//不要忘了最后一行进行刷新下布局if (i == getItemCount() - 1) {formatAboveRow();totalHeight += maxHeightItem;}}totalHeight = Math.max(totalHeight, getVerticalSpace());Log.d(TAG, "onLayoutChildren totalHeight:" + totalHeight);fillLayout(recycler, state);}//对出现在屏幕上的item进行展示,超出屏幕的item回收到缓存中private void fillLayout(RecyclerView.Recycler recycler, RecyclerView.State state) {if (state.isPreLayout() || getItemCount() == 0) { // 跳过preLayout,preLayout主要用于支持动画return;}// 当前scroll offset状态下的显示区域Rect displayFrame = new Rect(getPaddingLeft(), getPaddingTop() + verticalScrollOffset,getWidth() - getPaddingRight(), verticalScrollOffset + (getHeight() - getPaddingBottom()));//对所有的行信息进行遍历for (int j = 0; j < lineRows.size(); j++) {Row row = lineRows.get(j);float lineTop = row.cuTop;float lineBottom = lineTop + row.maxHeight;//如果该行在屏幕中,进行放置item
// if (lineTop < displayFrame.bottom && displayFrame.top < lineBottom) {List<Item> views = row.views;for (int i = 0; i < views.size(); i++) {View scrap = views.get(i).view;measureChildWithMargins(scrap, 0, 0);addView(scrap);Rect frame = views.get(i).rect;//将这个item布局出来layoutDecoratedWithMargins(scrap,frame.left,frame.top - verticalScrollOffset,frame.right,frame.bottom - verticalScrollOffset);}
// } else {
// //将不在屏幕中的item放到缓存中
// List<Item> views = row.views;
// for (int i = 0; i < views.size(); i++) {
// View scrap = views.get(i).view;
// removeAndRecycleView(scrap, recycler);
// }
// }}}/*** 计算每一行没有居中的viewgroup,让居中显示*/private void formatAboveRow() {List<Item> views = row.views;for (int i = 0; i < views.size(); i++) {Item item = views.get(i);View view = item.view;int position = getPosition(view);//如果该item的位置不在该行中间位置的话,进行重新放置if (allItemFrames.get(position).top < row.cuTop + (row.maxHeight - views.get(i).useHeight) / 2) {Rect frame = allItemFrames.get(position);if (frame == null) {frame = new Rect();}frame.set(allItemFrames.get(position).left, (int) (row.cuTop + (row.maxHeight - views.get(i).useHeight) / 2),allItemFrames.get(position).right, (int) (row.cuTop + (row.maxHeight - views.get(i).useHeight) / 2 + getDecoratedMeasuredHeight(view)));allItemFrames.put(position, frame);item.setRect(frame);views.set(i, item);}}row.views = views;lineRows.add(row);row = new Row();}/*** 竖直方向需要滑动的条件** @return*/@Overridepublic boolean canScrollVertically() {return true;}//监听竖直方向滑动的偏移量@Overridepublic int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,RecyclerView.State state) {Log.d("TAG", "totalHeight:" + totalHeight);//实际要滑动的距离int travel = dy;//如果滑动到最顶部if (verticalScrollOffset + dy < 0) {//限制滑动到顶部之后,不让继续向上滑动了travel = -verticalScrollOffset;//verticalScrollOffset=0} else if (verticalScrollOffset + dy > totalHeight - getVerticalSpace()) {//如果滑动到最底部travel = totalHeight - getVerticalSpace() - verticalScrollOffset;//verticalScrollOffset=totalHeight - getVerticalSpace()}//将竖直方向的偏移量+travelverticalScrollOffset += travel;// 平移容器内的itemoffsetChildrenVertical(-travel);fillLayout(recycler, state);return travel;}private int getVerticalSpace() {return self.getHeight() - self.getPaddingBottom() - self.getPaddingTop();}public int getHorizontalSpace() {return self.getWidth() - self.getPaddingLeft() - self.getPaddingRight();}
}
相关文章:

Android通过Recyclerview实现流式布局自适应列数及高度
调用 FlowAdapter 跟普通recyclerview一样使用 RecyclerView rvLayout holder.getView(R.id.spe_tag_layout); FlowAdapter rvAdapter new FlowAdapter(); FlowLayoutManager flowLayoutManager new FlowLayoutManager(); rvLayout.setLayoutManager(flowLayoutManager); r…...

AlexNet(fashion-mnist)
前言 AlexNet相较于LeNet-5具有更深的网络结构,采用relu激活函数。 AlexNet 参数更多,计算量更大,计算速度更慢,精度更高。 netnn.Sequential(nn.Conv2d(1,96,kernel_size11,stride4,padding1),nn.ReLU(),nn.MaxPool2d(kernel…...

2024新年烟花代码完整版
文章目录 前言烟花效果展示使用教程查看源码HTML代码CSS代码JavaScript 新年祝福 前言 在这个充满希望和激动的2024年,新的一年即将拉开帷幕,而数字科技的创新与发展也如火如荼。烟花绚丽多彩的绽放,一直以来都是新年庆典中不可或缺的元素。…...

Fontfabric:一款字体与设计的完美结合
一、产品介绍 Fontfabric是一款由国际字体设计公司Fontfabric开发的字体设计软件。它提供了一整套完整的字体设计工具,让用户可以轻松地创建、设计和定制自己的字体。Fontfabric拥有丰富的字体库,包括各种风格和类型,能够满足用户在不同场景…...

Python爬虫—requests模块简单应用
Python爬虫—requests模块简介 requests的作用与安装 作用:发送网络请求,返回响应数据 安装:pip install requests requests模块发送简单的get请求、获取响应 需求:通过requests向百度首页发送请求,获取百度首页的…...

江科大STM32
参考: https://blog.csdn.net/weixin_54742551/article/details/132409170?spm1001.2014.3001.5502 https://blog.csdn.net/Johnor/article/details/128539267?spm1001.2014.3001.5502 SPI:https://blog.csdn.net/weixin_62127790/article/details/132…...

银河麒麟Kylin-Server-V10-SP3使用ISO镜像搭建本地内网YUM/DNF源cdrom/http
机房服务器安装一般是内网环境,需要配置本地的YUM/DNF源。本文介绍通过ISO镜像搭建内网环境的UM/DNF源 准备工作: 提前准备好Kylin-Server-V10-SP3的ISO镜像文件。 本机IP地址:192.168.40.201 镜像存放目录/data/iso/Kylin-Server-V10-SP3-Ge…...

力扣第 379 场周赛VP
目录 一1.思路2.代码 二1.思路2.代码 三1.思路2.代码 四1.思路2.代码 链接:https://leetcode.cn/contest/weekly-contest-379/ 一 1.思路 找最长对角线,很显然直接比较a^2 b ^ 2就行 注意更新时考虑对角线长度相等时候去面积最大 2.代码 class Solution { publ…...

String intern()方法
String intern 方法有什么作用? String.intern() 是一个 native(本地)方法,其作用是将指定的字符串对象的引用保存在字符串常量池中,并返回常量池中对应的字符串引用。 当使用字面量创建字符串时,Java 会在编译期间自…...

springboot 物业管理系统
springboot mysql mybatisthymeleaf 基础信息管理 房屋信息 用户信息 业主信息 租房信息 公告管理 日常管理 财务管理...

K8S--- kubectl auth
该命令可以校验用户或者serviceaccount是否有对应的权限 [root@yyzc-zjjcs01 ~]# /opt/kubernetes/bin/kubectl --kubeconfig /opt/kubernetes/conf/default-admin.kubeconfig auth --help Inspect authorization Available Commands: can-i Check whether an action is allowe…...

HarmonyOS 开发基础(九)forEach
HarmonyOS 开发基础(九)forEach 一、基础使用 Entry Component struct Index {// 创建一个变量,用来存储图片网络网址imageUrl: string https://gw.alicdn.com/imgextra/i2/2201227850912/O1CN01B7gVvP1Ibk6HMiDRz_!!2201227850912.jpg_Q75.…...

【小黑嵌入式系统第十四课】μC/OS-III程序设计基础(三)——信号量(任务同步资源同步)、事件标记组(与或多个任务)
上一课: 【小黑嵌入式系统第十三课】PSoC 5LP第二个实验——中断控制实验 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站:人工智能 文章目录 1 信号量1.1 简介1.2…...

PMP报考流程?
项目管理相关证书,PMP是一个不错的选择,尤其是小白朋友。 PMP 是项目管理的一个入门证书,理论知识很全面,涵盖了项目管理的全流程,可作为日常工具参考书、完全小白的可以先考一个PMP学好理论,再考一个PRIN…...

【EI会议征稿通知】2024年机器学习与智能计算国际学术会议(MLIC 2024)
2024年机器学习与智能计算国际学术会议(MLIC 2024) 2024 International Conference on Machine learning and intelligent computing 智能计算与机器学习被广泛应用于大数据分析、人工智能、智能制造、智能交通、智能电网、智慧城市、智慧医疗、金融科…...

第八篇 提升网页性能:深入解析HTTP请求优化策略(三)
文章目录 1. 缓存策略设计1.1 HTTP缓存机制1.1.1 强缓存(Cache-Control/Expires)1.1.2 协商缓存(ETag/Last-Modified) 1.2 缓存位置1.2.1 浏览器缓存1.2.2 代理服务器缓存 1.3 缓存策略选择1.3.1私有缓存1.3.2 公共资源缓存 1.4 V…...

高版本ant-design动态引用icon
需求 最近在更新自己的博客系统,从 vue2 升到 vue3,同步的也把 ant-design 从 1.7.8 跨越多个大版本升级到了 4.0.8,发现菜单上的 icon 报错了。 查询官方文档发现自从 2.0 版本以后的 icon 就不再支持通过 <a-icon /> 组件动态 type…...

【SQL】delete 与 truncate 命令的区别
区别 truncatedelete属于 DDL(数据定义语言) 范畴属于 DML(数据操作语言) 范畴删除表数据,不能删除视图数据删除表数据,删除视图数据只可以梭哈删除通过 where 进行选择性删除不涉及事务处理删除表中数据涉及事务处理效率高、但无法撤销效率低ÿ…...

【ITK库学习】使用itk库进行图像分割(四):水平集分割
目录 1、水平集2、itkFastMarchingImageFilter 快速步进分割3、itkShapeDetectionLevelSetImageFilter 快速步进分割 1、水平集 水平集是跟踪轮廓和表面运动的一种数字化方法。基于图像的亮度均值、梯度、边缘特征的微分计算,进行水平集分割。在itk中,所…...

Kali Linux——aircrack-ng无线教程
目录 一、准备 二、案例 1、连接usb无线网卡 2、查看网卡信息 3、开启网卡监听 4、扫描wifi信号 5、抓取握手包 6、强制断开连接 7、破解握手包 三、预防 一、准备 1、usb无线网卡(笔记本也是需要用到) 2、密码字典(Kali 系统自带…...

15.vdo管理
vdo管理 文章目录 vdo管理一、VDO基本概念二、常用操作三、验证VDO卷 一、VDO基本概念 VDO(Virtual Data Optimize虚拟数据优化) 通过压缩或删除存储设备上的数据来优化存储空间。VDO层放置在现有块存储设备例如RAID设备或本地磁盘的顶部。这些块设备也…...

安全漏洞周报(2024.01.01-2023.01.08)
漏洞速览 ■ 用友CRM系统存在逻辑漏洞 漏洞详情 1. 用友CRM系统存在逻辑漏洞 漏洞介绍: 某友CRM系统是一款综合性的客户关系管理软件,旨在帮助企业建立和维护与客户之间的良好关系。它提供了全面的功能,包括销售管理、市场营销、客户服…...

msckf-vio 跑Euroc数据集,并用evo进行评估
所需材料: Euroc数据集主页:https://projects.asl.ethz.ch/datasets/doku.php?idkmavvisualinertialdatasetsevo评估工具代码:https://github.com/MichaelGrupp/evo向msckf-vio中添加保存位姿的代码,可参考https://blog.csdn.ne…...

大模型LLM在 Text2SQL 上的应用实践
一、前言 目前,大模型的一个热门应用方向Text2SQL,它可以帮助用户快速生成想要查询的SQL语句,再结合可视化技术可以降低使用数据的门槛,更便捷的支持决策。本文将从以下四个方面介绍LLM在Text2SQL应用上的基础实践。 Text2SQL概…...

数据库:园林题库软件(《城市绿地设计规范》答题卷一 )
《城市绿地设计规范》答题卷一 填空题 1、城市绿地设计应贯彻人与自然和谐共存、可持续发展、经济合理等基本原则,创造良好生态和景观效果,促进人的身心健康。 2、城市绿地 urban green space 以植物为主要存在形态,用于改善城市生态&am…...

MySQL之视图外连接、内连接和子查询的使用
目录 一. 视图 1.1 含义 1.2 视图的基本语法 1.3 视图的实操 二. 外连接、内连接和子查询的使用 2.1 SQL脚本 2.2 使用外连接、内连接和子查询进行解答 三. 思维导图 一. 视图 1.1 含义 视图(view)是一种虚拟存在的表,是一个逻辑表&#x…...

MoE模型性能还能更上一层楼?一次QLoRA微调实践
Fine-Tuning Mixtral 8x7B with QLoRA:Enhancing Model Performance 🚀 编者按:最近,混合专家(Mixture of Experts,MoE)这种模型设计策略展现出了卓越的语言理解能力,如何在此基础上进一步提升 MoE 模型的性能成为业界…...

Java线程学习笔记
1、判断线程存活 1. 当线程run()或者call()方法执行结束,线程进入终止状态 2. 当线程内发生异常,并且异常没有被捕获,线程进入终止状态 3. 线程调用stop()方法后,线程进入终止状态(不推荐使用) 当主线程结束时,其他线程…...

平面光波导_三层均匀平面光波导_射线分析法
平面光波导_三层均匀平面光波导_射线分析法 三层均匀平面光波导: 折射率沿 x x x 方向有变化,沿 y y y、 z z z 方向没有变化三层:芯区( n 1 n_1 n1) > > > 衬底( n 2 n_2 n2) ≥ \geq ≥ 包层( n 3 n_3 n3)包层通常为空…...

IPV6学习记录
IPV6的意义 从广义上来看IPV6协议包含的内容很多: IPV6地址的生成与分配 IPV6的报头的功能内容 IPV4网络兼容IPV6的方案 ICMPv6的功能(融合了arp和IGMP功能) IPV6的路由方式 ipv6的诞生除了由于ipv4的地址枯竭外,很大程度上也是因为ipv4多年的发展产生了很多…...