关于TListView或TListBox的当前视口及滚屏加载和刷新数据及FireMonkey应用
一、TListView或TListBox的当前视口跟设备屏幕的DP数值相关
与屏幕分辨率和像素密度PPI无关
与设备屏幕本身的物理或逻辑英寸数(用于计算分辨率与PPI相关)、或设备屏幕本身的物理尺寸【这些都为显示质量的衡量指标】:均不相关。
1、不同型号的终端显示设备,屏幕的DP(即屏幕的短边和长边尺寸)不同
屏幕的DP(即屏幕的短边和长边尺寸,这个尺寸为设计时的"点"尺寸),即 Screen.Width(或Screen.Size.CX)和 Screen.Height(或Screen.Size.CY):均为正整数。
2、屏幕的DP影响各类View的视口Viewport数值
(1)、比如这类View
TListView或TListBox
(2)、屏幕的DP数值和视口Viewport数值成比例
3、对视口Viewport的理解
(1)、手机POX系统和PC WIndows系统视口的处理方式不一
A、手机POX系统触发视口Viewport变化:
OnScrollViewChange :TListView
OnViewportPositionChange :TListBox
当滑屏时,视口高度ViewportPosition.Y连续变化(若横向滚屏,视口宽度ViewportPosition.X连续变化)
B、PC WIndows系统触发视口Viewport变化:
OnMouseWheel :TListView或TListBox
鼠标滚轮在默认的OnMouseWheel步长参数WheelDelta=1下,
滚轮每滚一下,ViewportPosition.Y变化21个Pixes像素(逻辑鼠标M220)
所以这种变化并不连续,取决于鼠标滚轮的精度
C、所以对手机和PC应当分别处理
但:取数方法统一,都通过ViewportPosition.Y来获取当前视口的高度:均为实数,可正可负。
当数据时,默认当前第一屏的视口的高度=0。
当手势滑屏或鼠标滚屏到View的顶部以上时,视口的高度<0。
当手势滑屏或鼠标滚屏到View的顶部以下时,视口的高度>0。
手势滑屏或鼠标滚屏:方向正好是相反的。
(2)、以手机POX系统为例
比方现在有数据加载到TListView或TListBox
那么其中加载的数据,屏幕纵向或横向,每屏可视的范围是不同的:
现在有3台设备,一台IPhone7、一台Andoid华为Chal(即荣耀A)、一台Andoid华为VIE-AL10(即P9Plus)
其竖屏DP(短边*长边)分别为: 376*667、360*640、360*600
如下图:
现在为其分别加载满屏数据后,并滚屏到最后一条记录:
ListViewMain.ScrollTo(ListViewMain.Items.Count - 1);
然后我们看看当前视口的数值(如下图):分别为 1383、1410、1450
DP长边数值越大的设备,其竖屏显示范围越大:
二、获取View中当前所加载数据的末尾索引行的视口高度
其视口数据的提取:AViewportPosition: TPointF;
AViewportPosition.Y := AListView.ScrollViewPos ; // AViewportPosition.Y := AListBox.ViewportPosition.Y ;
// 若TListView或TListBox设置为横向,则可取:AViewportPosition.X := AListView.ScrollViewPos ;
// AViewportPosition.X := AListBox.ViewportPosition.X ;
三、加载和刷新数据
1、加载和刷新数据的时机
因为后台每个数据对象,其数据量,都是伴随着平台伙伴的加入和使用,它是变化的,它是越来越大的。
所以:不要期待,一次性将服务端的后台数据,一次性全部下载到App本地,而应分段严格说分页取数。每下载一次数据分几页,取决于App设计时对效率的考量,影响效率的主因素有:并发用户数(与服务端CPU核心数和质量指标有关),每次取数时数据对象的数据矩阵的量即比特数(与服务端内存相关),相关技术架构。
通常:当手势滑屏或鼠标滚屏到View的数据的最底部即最后一条记录(或称View的最后一个索引行时),就必须重新下载一次分段数据,用以更多的加载View的数据显示。
特别的:为了用户体验更好,因为下载数据需要时,在未达到View的最后一个索引行时,就应重新下载一次分段数据。设计时应当设定一个App关于此项的标准。
比如:京东商城等App的加载效果。
这与前面一、二两节的知识和当前视口高度的数值ViewportPosition.Y的计算有关。
2、加载和刷新数据的技术原则
应当采用:
1、App客户端应用程序主窗体OnActive时一次性获取服务端所有数据对象当前的记录数,用于将来每个窗体做分页处理时直接使用,减少网络频繁调用、服务端网络带宽的瓶颈、服务端请求响应的并发瓶颈。
2、App客户端应用程序:空闲Idle时或某个正确的时机响应Active活动事件,将常用的数据(比如基础资料等)静默地以异步任务的方式下载到本地数据,用于客户端直接调用本地数据加载,进一步减少服务端和网络压力,同时提高客户端的执行效率和用户体验。
3、下载数据时,应当作分段分页处理。
4、使用多任务异步并行技术下载或上传数据,最大限度的使用多核CPU的处理能力(但应当计算本地CPU的核心数,留有冗余给操作系统处理其它相关(不要影响手机或PC正常的功能),比如8核,并发使用到6核就不要增加任务)。
5、App客户端使用多任务并行技术和线程池技术,不卡界面。
6、App Server服务端:多任务并行技术和线程池技术。
四、需要此技术的客户请联系QQ: 584798030
本博客关联:
1、《FireMonkey TListView的用法一:ItemAppearance为动态外观DynamicAppearance》 https://blog.csdn.net/pulledup/article/details/100634116
2、《FireMonkey TListView的用法二:ItemAppearance为客制化外观Custom》https://blog.csdn.net/pulledup/article/details/100977887
3、《关于TListView或TListBox的当前视口及滚屏加载和刷新数据及FireMonkey应用》https://blog.csdn.net/pulledup/article/details/100742272
4、《Delphi关于TListViewItem的对象名、成员名及TListItemView的方法》https://blog.csdn.net/pulledup/article/details/115141936
喜欢的话,就在下面点个赞、收藏就好了,方便看下次的分享: