UGUI进阶知识[二十九]循环GridView

news2024/11/16 16:29:01

节省内存的常用滑动列表还有一种形式,上下滑动的GridView。这种格式的滑动列表可用于移动设备的背包,仓库,商店UI等数据可能海量从而导致产生特别多但又看不见的UI的情况。

于是基于 UGUI进阶知识[八]循环利用滑动列表的循环ListView工程做了个更改。

主要工作在格子的初始化排布,整体区域的确定, 进入重新展示的循环之后,水平位置和对应数据的确定。

在listview总体逻辑思路确定了之后,根据思路在原代码基础上对应做这种改动还是比较容易的。

请添加图片描述

初始化排布

可见总项数的确定

将之前的水平计算变为水平和垂直计算,垂直计数+1是为了上下滑动的时候,格子位置突变的时候,还没有给用户划到,否则格子闪现会比较很违和。当滑动列表是水平滑动,则考虑水平计数加一。

 /// <summary>
    ///     获得总共需要的项数 包括多余的一项
    /// </summary>
    /// <param name="itemHeight"></param>
    /// <param name="verticalOffset"></param>
    /// <returns></returns>
    private int GetTotalShowItemNum(float itemHeight, float itemWidth,
        float verticalOffset, float horizontalOffset)
    {
        var height = GetComponent<RectTransform>().rect.height;
        var width = GetComponent<RectTransform>().rect.width;

        
        //这里多加的1是在显示区域外部 用来准备显示数据的一项
        verticalItemCount = Mathf.CeilToInt(height / (itemHeight + verticalOffset)) + 1;
        horizontalItemCount = Mathf.CeilToInt(width / (itemWidth + horizontalOffset)) ;

        int totalCount = horizontalItemCount * verticalItemCount;
        
        return totalCount;
    }

总大小确定

总数据数除以单行显示数据数等于数据行数,数据行数*单个item高度等于总高度,另外计入间隙。

 /// <summary>
    ///     设置总内容区域的大小为所有数据加载之后的大小
    ///     只是超出可显示部分是没有LoopGridListItem的
    /// </summary>
    private void SetContentSize()
    {
        int dataRowCount = loopGridListData.GetDataCount() / horizontalItemCount;
        
        var y = dataRowCount * _itemHeight +
                (dataRowCount - 1) * itemHorizonInterval;
         
        
        scrollRectContent.sizeDelta = new Vector2(scrollRectContent.sizeDelta.x, y);
    }

单个item的计算

是比起上面稍微烧脑一点的地方,按照习惯默认从上到下,从左到右id增大。计算的id用来确定位置和读取对应数据。

可见最大id和最小id的计算

在这里插入图片描述

   private void UpdateIdRange(out int toppestLeftId,  out int lowestRightId)
    {
       
        
        //当scrollRectContent对齐ScrollRect的时候 scrollRectContent.anchoredPosition.y是0
        //当scrollRectContent往上超出ScrollRect的时候 scrollRectContent.anchoredPosition.y大于0
        //toppestVisibleId表示 scrollRectContent滑动到当前位置 时候
        //可见的最顶部的item的id 部分可见也是可见 不是超出的item的id
        //FloorToInt是考虑到了顶部只显示部分item的情况 
        //此时toppestVisibleId应该是显示部分的item的时候,最左边的id
        toppestLeftId = Mathf.FloorToInt(scrollRectContent.anchoredPosition.y / 
                                            (itemHeight + itemVerticalInterval));
        
        //这里的计算表示的是最左边的id
        toppestLeftId *= horizontalItemNum;
        
        //lowestVisibleId表示可见的最底部的item的id
        //越往下 item的id越大
        lowestRightId = toppestLeftId + totalItemNum - 1;
        
        
    }

重新计算id

在这里插入图片描述

如图,顶部的三个是超出范围用户已经不可见的,下面是对这三个超出重新分配的id,根据id再去拿数据和设置位置。方法在OverflowRemedy中。

根据id重新设置位置

根据id对水平item个数求余求对应的列数,以及对水平item个数做除法求对应的行数。
然后根据UI的排布计算位置

  private void SetPos()
    {

        int horizonIndex = selfId % horizontalItemNum;
        int verticalIndex = Mathf.FloorToInt(selfId / horizontalItemNum) ;
            
            
        //每个LoopGridListItem所挂物体即预制体的Pivot是在自身的左上角 ,即滑动列表Content的原点在Content的左上角
        //每个LoopGridListItem从上到下的selfId是递增的
        //每个LoopGridListItem从上到下的anchoredPosition的y值是递减的
        //每个LoopGridListItem从左到右的anchoredPosition的x值是递增的
        //所以采用了这个计算方法
        Rect.anchoredPosition = new Vector2(horizonIndex * (itemWidth + itemHorizontalInterval),
            - verticalIndex * (itemHeight + itemVerticalInterval));
    }

对应数据的确定

在id计算好之后,对应的取数据逻辑不用改。

问题

  1. 在锚点设置为某种情况的时候,recttransform是没有任何属性和方法以及他们的组合计算能够获取实例化出来已经在canvas下的UI的宽高,这时的获取的值的规律和SizeDelta是一致的。 考虑的解决方法是重新临时设置锚点,在获取后再设置回去;或者在下一帧的时候再获取值,这明显是来自unity的bug了。补充在了 UGUI进阶知识[四]关于UI定位和适配。这里出问题的UI是实时实例化出来的,并非运行前摆放好。

  2. item的anchor和pivot应该调节成如下图所示,首先anchor应该聚集于一点,否则实例化item 的时候其宽高会因为父物体宽高不同而变得与预设体的宽高不一致,第一点已经验证了在这种情况下实例化UI的时候,不论anchor是否聚集还是散开,没有任何办法能拿到宽高,所以只有在预制体里面人工记录宽高。其他原因参考UGUI进阶知识[四]关于UI定位和适配
    在这里插入图片描述

  3. 在整个items的顶端或者底端,会有没有数据的部分,也就是说,已经滑动到了数据的底部部分没有数据了,这时再往上拖拽,还是会有循环的item出来。目前没有对这部分做处理,最简单的做法是限制ScrollRect在这部分不进行拉出。
    在这里插入图片描述

工程地址

Unity UGUI循环GridView

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

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

相关文章

普源1G带宽4通道10G采样率数字示波器MSO8104

超高性价比七合一 集成示波器在如今的集成设计领域&#xff0c;一款集成度较高的综合示波器已经成为设计工程师必不可少的得力工具。 MSO8000 系列数字示波器&#xff0c;它集 7 种独立仪器于一体&#xff0c;包括一台示波器、一台 16 通道逻辑分析仪、一台频谱分析仪、一台任…

煤矿电子封条建设实施方案算法 yolov7

煤矿电子封条建设实施方案算法通过yolov7网络模型深度学习技术&#xff0c;煤矿电子封条建设实施方案算法作为一种智能化安全新模式被广泛应用于各类场景中。YOLOv7 的发展方向与当前主流的实时目标检测器不同&#xff0c;研究团队希望它能够同时支持移动 GPU 和从边缘到云端的…

高完整性系统:Separation Logic for Automated Verification

目录 1. INTRODUCTION TO SEPARATION LOGIC 分离逻辑 1.1 霍尔推理&#xff08;Hoare Reasoning&#xff09; 1.2 堆指针的影响 1.3 全局和局部推理&#xff08;Global and Local Reasoning&#xff09; 1.4 组合推理&#xff08;Compositional Reasoning&#xff09; 1.…

chatgpt赋能python:Python中怎样输入数据以及数据类型

Python中怎样输入数据以及数据类型 Python是一种高级编程语言&#xff0c;常用于数据处理和分析、机器学习和Web开发等任务。输入数据是Python编程中的重要环节&#xff0c;因此本文将介绍Python中输入数据的方法和数据类型。 什么是数据输入&#xff1f; 数据输入是指将数据…

国内主流AI大模型盘点

今年年初&#xff0c;轰动科技圈的大事就是ChatGPT的面世&#xff0c;它的到来打响了AI智能时代的第一枪&#xff0c;同时展开了一场别开生面的智能科技革命。 随着ChatGPT迅速走红,国内各大企业纷纷发力认知大模型领域。经过一段时间的酝酿&#xff0c;国内的AI领域也开启了“…

StableStudio,比Midjourney还牛逼的绘画平台,免费!

大家好&#xff0c;我是鸟哥。 之前给大家推荐过Midjourney和Bluewillow两个AI绘画平台&#xff1a;简直了&#xff01;比Midjourney更刺激&#xff0c;还免费&#xff01;Midjourney功能超级强大&#xff0c;但比较傲娇&#xff0c;很贵&#xff0c;是否让用户免费体验要看心…

数据可视化系列指南之地图类图表大全

导语 随着数据在各行业中的应用越来越广泛&#xff0c;大家也逐渐认识到数据可视化在企业生产经营中的重要作用&#xff0c;在数据可视化过程中&#xff0c;图表是处理数据的重要组成部分&#xff0c;因为它们是一种将大量数据压缩为易于理解的格式的方法。数据可视化可以让受…

jar包和war包的区别;项目打包成jar或者war且运行在Linux上的tomcat

jar包和war包的区别&#xff1a; war包&#xff1a;通常是web应用后&#xff0c;例如网站&#xff0c;打成包部署到容器(可以是tomcat)中。含有包括WEB-INF包。war包通常就是放在tomcat包的/webapps下然后自动编译和运行。 jar包&#xff1a;通常是开发时要引用的类&#xff…

怎样使用Fiddler进行移动端抓包?附视频教程包你学会

目录 前言 抓包 什么是抓包 哪些场景下需要抓包 Fiddler Fiddler抓包原理 安装 Fiddler移动端抓包 第一步&#xff1a;允许远程计算机连接 第二步&#xff0c;设置手机网络代理 第三步&#xff0c;允许捕获HTTPS连接 第四步&#xff0c;手机安装证书 前言 本篇文章…

chatgpt赋能python:Python中如何提取字段中的数字

Python中如何提取字段中的数字 在数据分析和处理中&#xff0c;经常需要提取文本中的数字数据。在Python中&#xff0c;有多种方法可以实现这一操作。本篇文章将介绍Python中提取字段中的数字的方法&#xff0c;并给出示例代码。 使用正则表达式 正则表达式是Python中处理文…

二十、C++11(上)

文章目录 一、前言二、C11诞生简介三、列表初始化&#xff08;一&#xff09;{}初始化&#xff08;二&#xff09;initializer_list容器1. initializer_list 概念2. initializer_list的使用场景3. initializer_list接口函数模拟实现 四、关键字&#xff08;一&#xff09;auto&…

duilib中使用mfc控件

我在界面相隔挺远的位置添加2个mfc控件&#xff0c; 需要添加&#xff1a; 1. 添加 CMfcWndUI 类&#xff0c;这是为了调用mfc控件用的 2. 添加 duilib界面 CDuiFrameWnd 3.重写 2中界面的virtual CControlUI* CreateControl(LPCTSTR pstrClassName); 函数 需要注意的地方…

xray工具—代理扫描、爬虫扫描、Burp联动

xray工具—代理扫描、爬虫扫描、Burp联动 1. Xray介绍1.1. 支持漏洞检测类型1.2. 官网地址 2. 常用扫描模式2.1. 生成证书2.1.1. 浏览器安装证书 2.2. Xray基础主动扫描2.2.1. 基础主动扫描命令2.2.2. 基础主动扫描结果 2.3. Xray代理模式扫描2.3.1. 代理模式配置代理2.3.2. 代…

一场变革来到零售业,盖雅「劳动力账户」助力连锁门店全面管理人效

‍ 上半年&#xff0c;逐渐回暖的出游&#xff0c;为文旅和线下零售业的营收创造了希望&#xff0c; 但面对高周转率和低利润率的行业竞争格局&#xff0c;比起令人兴奋的营收&#xff0c;大部分零售企业仍在焦虑营收背后的成本。 或许是过去三年的环境让更多企业学会了「精…

Microsoft Build 两大主题:Copilots 和插件

在 Microsoft Build 中&#xff0c;贯穿会议的两个主要主题是 Copilots - 涵盖广泛产品和服务的 AI 助手 - 以及插件&#xff0c;它们有效地将 Copilots 转变为聚合器&#xff0c;可能使其成为企业和消费者客户的一站式商店。 微软MVP实验室研究员 张善友 深圳友浩达 CTO&…

Python:Python编程:金融量化交易

金融量化交易 1. numpy2. scipy3. Pandas3.1 : Series 3.2&#xff1a; DataFrame代码示例 在金融量化交易中&#xff0c;下面几个模块是应用的比较广泛的 numpy (Numberic Python) : 提供大量的数值编程工具&#xff0c;可以方便的处理&#xff1a;向量矩阵等运算&#xff0c;…

cuda编程学习——CUDA内存介绍(七)

前言 参考资料&#xff1a; 高升博客 《CUDA C编程权威指南》 以及 CUDA官方文档 CUDA编程&#xff1a;基础与实践 樊哲勇 文章所有代码可在我的GitHub获得&#xff0c;后续会慢慢更新 文章、讲解视频同步更新公众《AI知识物语》&#xff0c;B站&#xff1a;出门吃三碗饭 …

Linux 中断子系统中GIC 中断控制器基本分析

GIC 是 ARM 公司给 Cortex-A/R 内核提供的一个中断控制器&#xff0c;类似 Cortex-M 内核&#xff08;STM32&#xff09;中的 NVIC。 GIC&#xff1a;Generic Interrupt Controller&#xff0c;通用中断控制器。 NVIC&#xff1a;Nested Vectored Interrupt Controller&#…

RTX4060Ti上演史诗级尴尬,线下核心商区斩获个位数销量

时隔两年半&#xff0c;一代甜品 RTX 3060 Ti 显卡继任者 RTX 4060 Ti 终于上架了。 经过几天网上对比测试&#xff0c;情况就这么个情况&#xff0c;综合性能提升堪堪 10% 左右&#xff0c;价格上涨至 3199 元起。 来源&#xff1a;clubic 参考 RTX 4090 超 50% 性能提升&am…

聊聊 220V交流 过零检测

聊聊过零检测&#xff0c;以及如何实现过零检测 ...... by 矜辰所致目录 前言一、什么是过零检测1.1 为何需要过零检测 二、如何做过零检测2.1 光耦2.2 比较器/运放2.3 三极管/MOS管2.4 过零检测芯片 三、过零检测电路结语 前言 最近正好项目需求遇到需要做过零检测&#xff…