应用场景

对于背包界面,排行榜列表,聊天消息,等有大量的UI列表的界面,常规做法是为每一条数据生成一个格子,在数据量越大的情况下,会生成越来越多的Gameobject,引起卡顿。

这篇文章讲述的就是解决UI列表卡顿的方法,在列表中只生成指定数量的Gameobject,滑动时进行数据更新,保证性能。

LoopScrollRect(UGUI循环列表不卡顿)

插件地址:https://github.com/qiankanglai/LoopScrollRect

中文文档:http://qiankanglai.me/2015/08/15/LoopScrollRect/

适用于UGUI,支持UGUI原生的GridLayout,ScrollBar

我的修改版本:https://github.com/zhaoqingqing/LoopScrollRect.git

原理分析

在UGUI的ScrollRect基础上作的修改

两者的差异部分使用//==========LoopScrollRect========== 标识出来了,源代码对比:

UGUI的ScrollRect:https://bitbucket.org/Unity-Technologies/ui/src/5.2/UnityEngine.UI/UI/Core/ScrollRect.cs?fileviewer=file-view-default

LoopScrollRect:https://github.com/qiankanglai/LoopScrollRect/blob/master/Assets/Scripts/LoopScrollRect.cs

使用示例

可以参考demo的示例

如果在lua中使用,逻辑和C#的一样,步骤如下:

1.注册事件、取消注册

2.在刷新函数根据数据更新列表

3.调用逻辑

注册事件

注册列表滑动事件,在OnOpen中注册,用来刷新列表

此事件在C#中触发,Lua中注册回调,事件有两个参数

    self.chatScrollRect.dataSource.ScrollToTextEvent = function(cellTrans, idx) self:OnScrollChat(cellTrans, idx) end

取消注册

取消注册的列表滑动事件,在OnClose中取消

  self.chatScrollRect.dataSource.ScrollToTextEvent = nil

触发滑动事件(刷新每一项)

在以下情况事件会被触发:

  1. 如果列表的值已全部生成出来,在滑动过程中不会触发,否则会触发
  2. 调用RefreshCells或RefillCellsFromEnd时,会触发
function UIRewardResources:OnScrollEvent(cellTrans, idx)
if (not cellTrans or not idx) then
return
end
idx = idx + 1 -- Lua的索引从1开始,而scrollRect是从0开始
local data = DataCenter.resource.data[idx]
--执行你的刷新逻辑
self:DoRenderItem(cellTrans, data)
end

手动刷新列表

--设置列表的总数,并刷新cell
self.scrollRect.itemTypeStart = 0 ---让列表从头开始滑动
self.chatScrollRect.totalCount = 10
self.chatScrollRect:RefreshCells()

刷新并让列表滑动到底部

在聊天列表中每次发言完都是最新消息都在最底下,可以使用这个接口

self.chatScrollRect:RefillCellsFromEnd()

如果在模拟器上出现无法滑动到底部的现象,在Unity 2018.4.15f + 网易MuMu模拟环境下可添加下列代码

IEnumerator RefreshToEnd()
{
yield return null;
yield return null;
Canvas.ForceUpdateCanvases();
loop_scroll.verticalNormalizedPosition = 1.0f;
}

两个刷新函数区别

RefreshCells:列表刷新

RefillCellsFromEnd:从最底部的消息开始刷新,并滑动到底部

列表滑动到底部的事件

和UGUI的ScrollRect的做法一样,为scrollRect添加一个scrollbar,捕捉OnEndDrag事件,示例如下:

    self.chatScrollRect.onEndDrag = function(data)
if self.chatScrollbar.value >= 1 then
print("scroll to bottom")
end
end

如果你的数据量特别大,在滑动到底部事件时进行分页请求数据

如果是做分页:建议在滑动到某个数量级且滑动到底部时,设置一次数据,保证滑动的流畅性

prefabSource为nil

如果在热更新的包中报prefabSource为nil,是因为热更新dll之后,prefabSource会丢失,需要在lua对prefabSource重新赋值,示例:

self.scrollRect.prefabSource = CS.UnityEngine.UI.XLoopScrollPrefabSource(self.itemCell.gameObject)

跳转到指定的index/Item

参考:https://github.com/qiankanglai/LoopScrollRect/issues/14

方法一:

设置itemTypeStart为需要的Pos

	self.scrollRectEquipList.content.anchoredPosition = Vector2.zero
self.scrollRectEquipList.itemTypeStart = pos - 1
self.scrollRectEquipList.totalCount = equipCount
self.scrollRectEquipList:RefreshCells()

方法二:不绑定initInStart脚本,并调用 RefillCells(90)

两次调用列表滑动位置不正确

对于tab页签,左右切页都使用同一个ScrollRect,在前一个滑动到底部之后,再切到下一个页签,会出现列表还在滑动的现象,在切换页签前添加以下代码,停止上一次的滑动,并把位置进行复位

void ResetPos()
{
loop_scroll.StopAllCoroutines();
loop_scroll.StopMovement();
loop_scroll.content.anchoredPosition = Vector2.zero;
}

技巧和事项

Cell指:每一个格子,或每一项列表

为每一个Cell都绑定LayoutElement组件,并勾选Preferred Width 和Preferred Height,且给它们赋合适值,保证列表自适应。

查找某一项的取巧做法:可以用id做为Cell的名字,当在查找时,根据FindChild(id)找到这一项,进行刷新。

滑动到指定的index/Item:

https://github.com/qiankanglai/LoopScrollRect/issues/14

https://github.com/qiankanglai/LoopScrollRect/issues/27

[UI列表]LoopScrollRect无限滑动不卡顿的更多相关文章

  1. IScroll在某些手机浏览器上不能滑动和卡顿解决办法

    1.不能滑动,增加一句 if (scroll != null) scroll.refresh();2.卡顿,增加 <script>window.PointerEvent = undefin ...

  2. viewpager+fragment滑动切换卡顿问题

    最近在做项目的时候遇到个问题,viewpager中的fragment添加使用listview添加数据后出现滑动卡顿,造成用户体验感极差.找了很久的资料,也试了很多大方法,在这里给大家分享下: 1.添加 ...

  3. 性能优化九之UI卡顿分析

    在前一篇博客中提到内存抖动和耗时复杂的计算会导致UI卡顿. 那为什么内存抖动会导致UI卡顿呢? 其实在 性能优化一之内存与垃圾回收器 这篇文章中已经有所提及. 这里来详细说明一下: 渲染功能是应用程序 ...

  4. ios添加-webkit-overflow-scrolling依然卡顿

    项目由vue-cli2创建 在overflow: auto区域内滑动ios手机出现卡顿,搜索资料后添加-webkit-overflow-scrolling: touch ios bug: 1.滑动区域 ...

  5. Android异常与性能优化相关面试问题-ui卡顿面试问题详解

    UI卡顿原理: “60fps(Frames Per Second每秒传输帧数) ----> 16ms” 针对上面标红的数字,下面具体说明一下:最主要的根源在于渲染性,Android会每隔16ms ...

  6. Android ListView只加载当前屏幕内的图片(解决list滑动时加载卡顿)

    最近在做ListView分页显示,其中包括图片 和文字(先下载解析文字内容,再异步加载图片)发现每次点击下一页后,文字内容加载完毕,马上向下滑动,由于这时后台在用线程池异步下载图片,我每页有20条,也 ...

  7. bootsrtap h5 移动版页面 在苹果手机ios滑动上下拉动滚动卡顿问题解决方法

    bootsrtap h5 移动版页面 在苹果手机ios滑动上下拉动滚动卡顿问题解决方法 bootsrtap框架做的h5页面,在android手机下没有卡顿问题,在苹果手机就一直存在这问题,开始毫无头绪 ...

  8. Android Scrollview嵌套RecyclerView导致滑动卡顿问题解决

    一个比较长的界面一般都是Scrollview嵌套RecyclerView来解决.不过这样的UI并不是我们开发人员想看到的,实际上嵌套之后.因为Scrollview和RecyclerView都是滑动控件 ...

  9. Android 界面滑动卡顿分析与解决方案(入门)

    Android 界面滑动卡顿分析与解决方案(入门) 导致Android界面滑动卡顿主要有两个原因: 1.UI线程(main)有耗时操作 2.视图渲染时间过长,导致卡顿 目前只讲第1点,第二点相对比较复 ...

随机推荐

  1. C#中的静态成员和非静态成员

    C#的类中可以包含两种方法:C#静态方法与非静态方法.那么他们的定义有什么不同呢?他们在使用上会有什么不同呢? 让我们来看看最直观的差别:使用了static 修饰符的方法为静态方法,反之则是非静态方法 ...

  2. 前端面试题(3) cookie,sessionStorage和localStorage的区别

    cookie是网站为了标示用户身份存在用户本地终端上的数据(经过加密). cookie数据时钟在同源的http请求中携带(即使不需要),即会在浏览器和服务器之间传递. seeeionStorage和l ...

  3. 使用JavaMail发送带附件的邮件

    所需jar包 链接:http://pan.baidu.com/s/1dFo4cDz 密码:akap 工具类: package com.javamail.utils; import java.util. ...

  4. react 体验 react与vue的比较

    用了 vue 大半年了,不过我在2016年暑假的时候就看到了 react 这个项目,有点想学习一番,之前学习的都是基础语法和一些基础用法吧,总的来说 mvvm 框架确实都很相似,会一个就可以了; 今天 ...

  5. Unity3D游戏xlua轻量级热修复框架

    这是什么东西 前阵子刚刚集成xlua到项目,目的只有一个:对线上游戏C#逻辑有Bug的地方执行修复,通过考察了xlua和tolua,最终选择了xlua,原因如下: 1)项目已经到了后期,线上版本迭代了 ...

  6. FreeMarker 快速入门

    FreeMarker 快速入门 FreeMarker是一个很值得去学习的模版引擎.它是基于模板文件生成其他文本的通用工具.本章内容通过如何使用FreeMarker生成Html web 页面 和 代码自 ...

  7. ndk-stack使用方法

    最近在mac上编译android 版本,各种崩溃让人蛋疼,网上学习了下ndk-stack使用方法. 自己备忘下: 1.运行终端. 跳转到你android sdk 目录 因为你的adb 在里面. 如 c ...

  8. Python开发目录

    Python开发目录 Python之三目运算符 Python之文件的基本操作

  9. android studio 目录结构讲解

    android studio 目录结构讲解 src 毫无疑问,src目录是放置我们所有 Java代码的地方,它在这里的含义和普通 Java 项目下的 src目录是完全一样的,展开之后你将看到我们刚才创 ...

  10. 熟悉Objective—C

    1.oc使用消息结构而非函数调用 使用消息结构的语言,运行时所应执行的代码由运行环境来决定,而是用函数调用的语言,则由编译器决定.函数调用:如果调用的函数是多态的,那么在运行时就要按照“虚方法表”来查 ...