27.HarmonyOS App(JAVA)可复用列表项的ListContainer

可复用列表项的ListContainer

 
简短的列表可以通过定向布局实现,但是如果列表项非常多,则使用定向布局就不再合适。如需要创建50个列表项的列表,那么用定向布局实现至少需要创建50个以上的组件了。然而,限于设备屏幕大小的限制,绝大多数组件不会显示在屏幕上,却会占据大量的内存资源,甚至导致应用“闪退”。

与其他移动开发技术一样,鸿蒙操作系统也提供了可复用列表项的列表组件ListContainer。

注意: 在Android和IOS系统中,均提供了与ListContainer类似的可复用列表项的列表组件。在安卓系统中,这种组件被称为RecyclerView; 在IOS系统中,这种组件被称为UITableView。

ListContainer继承于ComponentContainer,属于布局的一种。

在ListContainer中,每个列表项都是一个组件或者子布局,即列表项组件。不过,ListContainer非常“吝啬”。

例如,利用ListContainer实现具有50个列表项的列表,ListContainer绝对不会实实在在地创建50个组件,而是仅创建屏幕当前能够显示的列表项组件。

例如,当前的设备屏幕只能够显示六个列表项,那么ListContainer只创建六个列表项组件。当用户上下滑动到其他的列表项时,被滑出去的列表项组件会被新的列表项复用,重新更换数据后再次进入用户的视野,如图1所示。

在图1中,Item 1组件被滑出列表,随后被ListContainer“换装”填入新的数据后再次从列表底部重新进入ListContainer。Item 1组件和Item 7组件实际上是1个组件,组件还是原来的组件,只不过数据已经不是原来的数据了。这种按需创建组件的思想对于应用程序能够流畅稳定地运行非常重要。这么说来,ListContainer就像一个掌管着系统资源的大臣,时时刻刻打着精细的算盘,用最少的内存资源来干更多事情。

那么,我们应该如何来使用ListContainer呢? 实际上,ListContainer已经封装好复用列表项的机制了,不需要开发者过多操心。作为开发者,只需为ListContainer提供需要显示的列表项所需要的数据和组件就可以了,而这项工作就全权交给RecycleItemProvider类完成了。RecycleItemProvider是一个抽象类,开发者在使用它之前需要至少实现以下4种方法。

(1) getCount(): 提供列表项数量。

(2) getItem(int i): 提供当前列表项的数据。

(3) getItemId(int i): 提供当前列表项ID。

(4) getComponent(int id,Component cpt,ComponentContainer ctn): 创建组件与数据绑定,即创建属于这个列表项的组件,然后绑定该列表项数据。在这种方法中,id表示这个列表项ID,cpt对象为上一次这个列表项的组件对象。作为开发者可以直接复用这个组件对象,当然也可以创建一个新的组件对象。ctn是cpt组件的父布局对象。

ListContainer和RecycleItemProvider的具体使用方法。

首先,通过布局文件(recycle_item.xml)创建列表项的用户界面,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_content"
    ohos:width="match_parent"
    ohos:orientation="vertical">
    <Text
        ohos:id="$+id:item_text"
        ohos:height="match_content"
        ohos:width="match_parent"
        ohos:margin="5vp"
        ohos:text_size="15fp"
        ohos:text_alignment="center"/>


</DirectionalLayout>

这个列表项非常简单,仅仅显示了一个文本组件,用于显示列表项数据,但是,这个用户界面与之前介绍的AbilitySlice界面不同,这个列表项界面仅仅显示在屏幕的某一个部位,因此不能使用之前的setUIContent方法了。

此时,需要LayoutScatter类来解析这个布局文件,LayoutScatter并不能直接被初始化,需要通过其getInstance(Context context)方法获取,其中content为当前的上下文对象。获取LayoutScatter 对象后,通过其parse(int xmlId,ComponentContainer root,boolean attachToRoot)方法即可解析所需要的XML布局文件,并且转换为组件对象。在parse方法中,xmlId表示需要解析的布局资源ID。当attachToRoot参数为true时,可以将解析出来的组件对象自动添加到root布局中,但是,在绝大多数情况下并不需要这么做,此时传递root参数为null,传递attachToRoot参数为false即可。

ability_main.xml

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:alignment="center"
    ohos:orientation="vertical">

    <ListContainer
        ohos:id="$+id:list_container"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:orientation="vertical"
        />

</DirectionalLayout>

MainAbilitySlice.java

package com.example.myapplication.slice;

import com.example.myapplication.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;

import java.util.ArrayList;
import java.util.List;

public class MainAbilitySlice extends AbilitySlice {
    private ListContainer mListContainer;
    private List<Integer> mNumbers;
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        mNumbers = new ArrayList<>();
        for(int i =0;i<50;i++)
        {
            mNumbers.add(i+1);
        }
        //获取ListContainer对象
        mListContainer = (ListContainer) findComponentById(ResourceTable.Id_list_container);
        //为ListContainer对象设置RecycleItemProvider
        mListContainer.setItemProvider(new RecycleItemProvider() {
            @Override
            public int getCount() {
                return mNumbers.size(); //列表项数
            }

            @Override
            public Object getItem(int i) { //当前列表项数据
                return mNumbers.get(i);
            }

            @Override
            public long getItemId(int i) {
                return i; //当前列表项ID
            }

            @Override
            public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
                //列表项用户界面,如果可复用之前的界面,则直接复用
                DirectionalLayout layout = (DirectionalLayout) component;
                if(layout == null)
                {
                    //如果之间的界面为空,则创建新的列表项用户界面
                    layout = (DirectionalLayout) LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_recycle_item,null,false);
                }
                //获取列表项中的文本组件
                Text text = (Text) layout.findComponentById(ResourceTable.Id_item_text);
                //设置列表项数据
                text.setText("当前数据:"+getItem(i).toString());
                //返回该列表项的用户界面

                return layout;
            }
        });


    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CentOS 7.9.2009离线安装mysql 8.0客户端 (rpm包)

环境&#xff1a; #需求&#xff1a; 该服务器需要将csv文件入库到远端的mysql 服务器上。 CentOS Linux release 7.9.2009 (Core) 离线环境 &#xff0c;需安装mysql客户端 8.0.27#下载地址 https://downloads.mysql.com/archives/community/#按此顺序安装 rpm -ivh mysql…

C++ //练习 9.16 重写上一题的程序,比较一个list<int>中的元素和一个vector<int>中的元素。

C Primer&#xff08;第5版&#xff09; 练习 9.16 练习 9.16 重写上一题的程序&#xff0c;比较一个list中的元素和一个vector中的元素。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /**********************************…

AMEYA360 | 罗姆的EcoGaN™被台达电子Innergie品牌的45W输出AC适配器“C4 Duo”采用!

全球知名半导体制造商ROHM Co., Ltd.(以下简称“罗姆”)的650V GaN器件(EcoGaN™)&#xff0c;被台达电子(Delta Electronics, Inc.&#xff0c;以下简称“台达”)Innergie 品牌的45W输出AC适配器(快速充电器)“C4 Duo” 采用。台达是基于IoT技术的绿色解决方案全球供应商。Inn…

AGI|教你用一部电影的时间训练个人专属Agent

目录 一、Agent如何工作&#xff1f; 二、Function Call 原理 三、开源模型工具调用微调 //Chat模型微调 //训练过程日志 //测试结果 //测试Tools 四、预训练模型微调 五、总结 Agent是一个超越简单文本生成的人工智能系统。它使用大型语言模型&#xff08;LLM&#x…

CS_上线三层跨网段机器(完整过程还原)

以前讲过用cs_smb_beacon上线不出网机器&#xff0c;但是真实的网络拓扑肯定不止这么一层的网络&#xff01; 所以我就来搭建一个复杂一点的网络环境&#xff01;&#xff01; 当然了&#xff0c;这三台电脑之间都是不同的网段&#xff0c;&#xff08;但是同属于一个域环境&a…

MySQL数据库进阶第五篇(锁)

文章目录 一、锁的概述二、全局锁三、表级锁四、元数据锁&#xff08;meta data lock, MDL&#xff09;五、意向锁六、行级锁七、行锁&#xff08;Record Lock&#xff09;八、间隙锁&#xff08;Gap Lock&#xff09;九、临键锁&#xff08;Next-Key Lock&#xff09;十、锁总…

遇见数字孪生城市美好模样 国产GIS加速创新竞逐“新赛道”

在未来数字孪生城市中&#xff0c;每一座建筑、每一条道路、每一盏路灯、每一辆车&#xff0c;甚至每一个人&#xff0c;都有其对应的数字孪生体。这些数字孪生体在虚拟世界中形成了城市的细致模型&#xff0c;如同镜子一样&#xff0c;反映出城市的实时状态&#xff0c;同时也…

Datawhale-Sora技术原理分享

目录 Sora能力边界探索 Sora模型训练流程 Sora关键技术拆解 物理引擎的数据进行训练 个人思考与总结 参考 https://datawhaler.feishu.cn/file/KntHbV3QGoEPruxEql2c9lrsnOb

HTB pwn Dragon Army

逆向分析 程序使用了alloca函数扩大了栈区 此处可以泄露libc的地址 程序主要功能在下面 while ( 1 ){while ( 1 ){fflush(stdin);fflush(_bss_start);fprintf(_bss_start, "\n%sDragons: [%d/%d]%s\n\n", "\x1B[1;34m", v5, 13LL, "\x1B[1;37m"…

山海鲸可视化:数据分析师的明智之选

作为一名资深的数据分析师&#xff0c;我深知数据可视化在数据分析和决策制定中的重要性。在众多的数据可视化工具中&#xff0c;我最终选择了山海鲸可视化软件。本文就简单介绍几点我选择它的主要原因&#xff1a; 首先&#xff0c;山海鲸可视化软件提供了强大的数据整合能力…

MySQL-事务,properties文件解析,连接池

1.事务机制管理 1.1 Transaction事务机制管理 默认情况下是执行一条sql语句就保存一次&#xff0c;那么比如我们需要三条数据同时成功或同时失败就需要开启事务机制了。开启事务机制后执行过程中发生问题就会回滚到操作之前&#xff0c;相当于没有执行操作。 1.2 事务的特征 事…

sql-labs25-28a

一、环境 网上都有不过多阐述 二、sql-labs第25关 它说你的OR和and属于它,那就是过滤了OR和and 注入尝试 不用or和and进行爆破注入,很明显是有注入点的 ?id-1 union select 1,2,3-- 查看数据库 ok&#xff0c;此道题算是解了但是如果我们用了and了呢 ?id-1 and updatex…

消息中间件篇之Kafka-高性能设计

一、高性能设计 消息分区&#xff1a;不受单台服务器的限制&#xff0c;可以不受限的处理更多的数据。 顺序读写&#xff1a;磁盘顺序读写&#xff0c;提升读写效率。 页缓存&#xff1a;把磁盘中的数据缓存到内存中&#xff0c;把对磁盘的访问变为对内存的访问。 零拷贝&a…

C# 水排序 微信小游戏

来只 水排序谜题启发式搜索方法_水排序解法小程序-CSDN博客 大神的C语言转换成C# 语言&#xff0c;更多的请看原作者&#xff0c;这里直接贴C#代码 using System; using System.Collections.Generic; using System.Linq; using System.Text;namespace ConsoleApp2 {class Pro…

SImpAl

output matrix M&#xff0c;Curriculum using w ( x t , f , h ) w(x_t, f, h) w(xt​,f,h) 辅助信息 作者未提供代码

想露一手Linux命令,掌握这20个够用了!

中午好&#xff0c;我的网工朋友。 想做好网工&#xff0c;除了路由交换&#xff0c;掌握Linux操作系统也是很重要的。 因为很多服务器上都是用的Linux系统&#xff0c;要和服务器机器交互&#xff0c;就要通过Linux的相关命令。 正在找工作的朋友&#xff0c;如果面试时&am…

thinkphp6定时任务

这里主要是教没有用过定时任务没有头绪的朋友, 定时任务可以处理一些定时备份数据库等一系列操作, 具体根据自己的业务逻辑进行更改 直接上代码 首先, 是先在 tp 中的 command 方法中声明, 如果没有就自己新建一个, 代码如下 然后就是写你的业务逻辑 执行定时任务 方法写好了…

leetcode 2867. 统计树中的合法路径数目【筛质数+贡献法】

原题链接&#xff1a;2867. 统计树中的合法路径数目 题目描述&#xff1a; 给你一棵 n 个节点的无向树&#xff0c;节点编号为 1 到 n 。给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges &#xff0c;其中 edges[i] [ui, vi] 表示节点 ui 和 vi 在树中有一条边。 …

openai sora 只能根据文本生成视频?不,TA 是通用物理世界模拟器

视频生成模型作为世界模拟器 我们探索了在视频数据上进行大规模生成模型的训练。 具体来说&#xff0c;我们联合在可变持续时间、分辨率和长宽比的视频和图像上训练文本条件扩散模型。 我们利用了一个在视频和图像潜在编码的时空补丁上操作的变压器架构。 我们最大的模型So…

请求包的大小会影响Redis每秒处理请求数量

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容压测规划客户端长连接数量对性能的影响请求包大小的影响Pipleline模式对Redis的影响 &#x1f4e2;文章总结&#x1f4e5;博主目标 &#x1f50a;博主介绍 &#x1f31f;我是廖志伟&#xff0c;一名Java开发工程师、Java领…