GList列表添加拉到底会自动消失的向下箭头功能小记

前言:Fairgui是一个很好用的UI工具,但是他跟其他UI一样,事件的通知都有很大的缺失,都仅仅提供一些常用的。
非游戏的ui框架,对于ui的变化都会通知到编写者,比如一个列表,item大小发生变化会通知,item被点击会通知,发生滚动会通知,显示区域item发生变化会通知,滚到低会通知等等。
显然,fairgui里面发生的很多变化,编写者根本不知道,除非你update里面每秒去检测他,而且还缺乏判断标准,例如,GList添加拉到底会自动消失的向下箭头,仅仅使用fairgui的东西,如何判断列表滚到底了?
正文:
我思考了片刻,决定利用虚拟列表不会把item全部显示出来的特性,是不是说当index+1==numItems的时候,就代表list滚到底,或者接近滚到底了?
于是我开始尝试。(测试列表是一个N行1列的传统排行榜形式的列表)
第一次尝试:
itemRenderer里直接判断当index+1==numItems的时候隐藏箭头,否则显示箭头(因为item的显示肯定是有序的,默认从小到大)
然后发现失败,拉到底再往上拉的时候,再次显示箭头有较大延迟,因为glist会准备几个item,所以最下面的几个item虽然离开显示区域了,但是并没有隐藏,还是显示着。
第二次尝试:
numItems=numItems+1,多显示一个(流动表格就+列数);然后
itemRenderer里当index+1<=numItems,显示箭头,并把item设置为设定大小(可以一开始保存下),alpha=1,enabled=true;否则,隐藏箭头,并把item设置为设定宽度(可以一开始保存下),高度为1,alpha=0.01,enabled=false;
后来发现偶尔会对某些排版关联方式有一定影响,而且移植到流动形式的表格上,会有错乱的情况。失败。
第三次尝试:
numItems=numItems+1,多显示一个;并且创建一个高度为1的空白组件。利用itemProvider,并不改变item大小,而是把多出来的item指定为高度为1的空白组件。
---@return string
function SelfServerRankWindow.CountryPowerItemProvider(index)
local tableLength = 0
for k, v in pairs(serviceTool.GetCountryPowerData().infos) do
tableLength = tableLength + 1
end

if index+1 >tableLength then
return EmptyItem
end

return countryPowerItem
end
上面是lua的代码,差不多就是这形式。
然后itemRenderer里当index+1<=numItems,显示箭头,否则隐藏。
这个方式我一度认为是正确可用的,发现就发现了问题,上下正常拉动都是正常的,但是当我把list拉到底,箭头消式以后,我再拉上去一点点拉到箭头显示,然后立马拉到底,箭头没消失!
观察发现,当时我list拉到底再拉上去一点点到箭头显示,再往下拉的过程,gameobject的表示只是有一个item被隐藏了,但是没有item从隐藏变成显示,itemRenderer完全就没触发,我根本就不知道!再次失败。
第四次尝试:
在第三次尝试的基础上,我已经无计可施,只能动源码了,GList里面加一个共有字段,并且默认为false,以免你的改动影响到其他人。
/// <summary>
/// 如果true,则滚动List的时候会强制刷新所有item,慎用
/// </summary>
public bool openScrollFroceUpdate = false;
然后修改GList里面void __scrolled(EventContext context)这个方法。改成:
void __scrolled(EventContext context)
{
HandleScroll(openScrollFroceUpdate );
}
目前来说,效果都很正常,如果发现问题,那么我会来个第五次尝试。
改源码的缺点就是,fairgui的版本要稳定一个版本,不然一升级可能就没了。
------------------------------------------------------------------------------
发现了缺点,性能上有点缺失,特别是动态装配扩容,大小不一并且特别复杂的item,比如用到
EnsureBoundsCorrect()进行扩展的item,它....有点卡。
我的方法暂时是优化下item,不要做非必要的工作。
-------------------------------------------------------------------------------
第五次尝试:
想办法解决性能问题,去掉第四次的代码,或者将openScrollFroceUpdate设置为false
在GList中加上一行
/// <summary>
/// 如果true,则List最后一个item总是会被刷新,慎用
/// </summary>
public bool endItemAlwaysUpdate = false;
在bool HandleScroll1(bool forceUpdate),bool HandleScroll2(bool forceUpdate)的if (needRender)上面加上
else if(curIndex+1 == _realNumItems && endItemAlwaysUpdate)
needRender = true;

f1.png


------------------------------------------
第四种不适合复杂List,很卡,但是恢复很及时。
第五种恢复的时候有点延时,但不影响性能。
--------------------------------------------------
第六次尝试:
经过版主的提示教育,确实发现走了远路。
GList使用的是GComponent里面的scorllpanel,用这个判断percY==1确实可行。
 
再次补充
版主的方法有缺陷,当list里面元素过少不会触发滚动的时候,percY始终是0
需要在判断contentHeight是否为0,为0代表未达到滚动条件的情况。
或者我在api文档里面找到一个isBottomMost的属性,好像也可以。
就认为滚到底无法检测这件事情来说,确实是我不够熟悉造成的。

6 个评论

写那些多,首先还是感谢你的分享。
但你还是不熟fgui,才会得出缺失很多功能这个结论。然后你改的一堆东西,你知道有多少坑吗,列表,虚拟列表这些东西,本身就是很复杂,经过大量迭代才稳定下来的,你随意就改了。
拉动到最后获得通知,你可以直接侦听scroll事件,判断percX/percY=1就是了,不觉得有多麻烦。
感谢你的建议,我会去试试你的方法。
但是你所谓的迭代,不是你不做这个功能的原因,别的UI可以做到,他们不需要迭代?
主要是我对fgui期望比较大吧。
可能确实存在对fgui不熟的情况,但是缺失的问题确实存在。
比如,我有100个不同位置的元件,相同的关联适配方式,比如左->左%,顶->顶%,我必须每个原件都去适配一次?或者不得不搞一个组,去设置这个组?
比如之前我回答的滚动容器缓动,我看了你们的源码,缓动触发的距离,是一个常量固定值。
你们可能要说,这是一个历经多次迭代手感最好的一个值。
但是也许使用却不需要你们所谓的手感最好,我们就是要调整这个缓动的触发距离,怎么办?
你们能不能只提供一个效果最好的默认值,至于改了效果好不好,应该不需要框架去操心,而是交给使用者去权衡。
不知道为什么要大量使用常量参数,或者私有的参数,也许是太操心我们用得好不好?
unity他是一个游戏引擎,ugui只是一个它其中的一个模块,我能理解ugui为什么做得不够强大不够灵活。
作为一个专业的ui框架,我觉得不应该局限于某些引擎的可选ui插件,应该去对标那种强大的桌面级ui框架,比如说qt。
当然,语言不同,环境不同,应用领域不同,造成了并不能完全借鉴,但是我个人觉得能借鉴的地方还是很多的,比如他的布局器,有多么强大灵活,相信用过的都知道。比如事件(信号),绝大多数的变化,使用者都是可选择监听的。
当然灵活带来的负面效果,比如性能,不稳定性,就交给使用者去权衡,去承担。
我就事论事,只是评价你这此文提出的这个问题,不需要去自己改动,更不要像你那样去改,因为改得并不对。
但其他功能有没有问题,当然可能有啊,哪有完美的东西,它也在继续迭代。我没有阻止你自己去优化,但你分享给别人,如果有错,我就不得不指出。
我没用过QT,也知道它的强大,但它具体强大在哪里,我不清楚。我只清楚一点,没人用它开发游戏就是了。我觉得你用一个东西,一开始就想着和其他东西对比,而不是深入了解它,那你会觉得它全是缺点咯。
然而你们并不是游戏引擎,而是UI框架。
他的设计理念,布局方案,内部UI的事件(外部消息队列基于平台的不同,就不借鉴了),应该是可以一定程度上借鉴的。
还是那个想法,为什么非要把把自己定位定死呢。
“我们是游戏的UI,其他的UI都是不灵活不好用的,我们比他们还用得多,那么就够了。别人说的,又没有人拿来做游戏,所以好不好用跟我们没关系。”
我不否认fgui有许多优点,比如控制器,我就觉得做得很棒。但是我觉得fgui可以更棒,更强大,更通用,满足更多需求。
所以虽然这篇文章在没有足够资料的背景下走了一些弯路。
但是我还是不会收回,fgui仍有一些东西可以做得更好更灵活更强大,这种看法。
明明可以成为行业标杆,却非要对标ugui、ngui这些残缺品,他们真的足够强大,还会有人跑来用fairgui吗

要回复文章请先登录注册