HarmonyOS —常用组件开发指导-ListContainer

HarmonyOS —常用组件开发指导-ListContainer

ListContainer是用来呈现连续、多行数据的组件,包含一系列相同类型的列表项。

支持的XML属性

ListContainer的共有XML属性继承自:Component

ListContainer的自有XML属性见下表:

属性名称中文描述取值取值说明使用案例
rebound_effect开启/关闭回弹效果boolean类型可以直接设置true/false,也可以引用boolean资源。ohos:rebound_effect=”true”ohos:rebound_effect=”$boolean:true”
shader_color着色器颜色color类型可以直接设置色值,也可以引用color资源。ohos:shader_color=”#A8FFFFFF”ohos:shader_color=”$color:black”
orientation列表项排列方向horizontal表示水平方向列表。ohos:orientation=”horizontal”
vertical表示垂直方向列表。ohos:orientation=”vertical”

ListContainer的使用方法

在layout目录下,AbilitySlice对应的布局文件page_listcontainer.xml文件中创建ListContainer。

<ListContainer

ohos:id=”$+id:list_container”

ohos:height=”200vp”

ohos:width=”300vp”

ohos:layout_alignment=”horizontal_center”/>

在layout目录下新建xml文件(例:item_sample.xml),作为ListContainer的子布局。

<?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:left_margin=”16vp”

ohos:right_margin=”16vp”

ohos:orientation=”vertical”>

<Text

ohos:id=”$+id:item_index”

ohos:height=”match_content”

ohos:width=”match_content”

ohos:padding=”4vp”

ohos:text=”Item0″

ohos:text_size=”20fp”

ohos:layout_alignment=”center”/>

</DirectionalLayout>

创建SampleItem.java,作为ListContainer的数据包装类。

public class SampleItem {

private String name;

public SampleItem(String name) {

this.name = name;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

ListContainer每一行可以为不同的数据,因此需要适配不同的数据结构,使其都能添加到ListContainer上。创建SampleItemProvider.java,继承自BaseItemProvider。必须重写的方法如下:方法作用int getCount()返回填充的表项个数。Object getItem(int position)根据position返回对应的数据。long getItemId(int position)返回某一项的id。Component getComponent(int position, Component covertComponent,ComponentContainer componentContainer)根据position返回对应的界面组件。代码示例如下:

// 请根据实际工程/包名引入

import com.example.myapplication.ResourceTable;

import ohos.aafwk.ability.AbilitySlice;

import ohos.agp.components.*;

import java.util.List;

public class SampleItemProvider extends BaseItemProvider {

private List<SampleItem> list;

private AbilitySlice slice;

public SampleItemProvider(List<SampleItem> list, AbilitySlice slice) {

this.list = list;

this.slice = slice;

}

@Override

public int getCount() {

return list == null ? 0 : list.size();

}

@Override

public Object getItem(int position) {

if (list != null && position >= 0 && position < list.size()){

return list.get(position);

}

return null;

}

@Override

public long getItemId(int position) {

//可添加具体处理逻辑

return position;

}

@Override

public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {

final Component cpt;

if (convertComponent == null) {

cpt = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_item_sample, null, false);

} else {

cpt = convertComponent;

}

SampleItem sampleItem = list.get(position);

Text text = (Text) cpt.findComponentById(ResourceTable.Id_item_index);

text.setText(sampleItem.getName());

return cpt;

}

}

在Java代码中添加ListContainer的数据,并适配其数据结构。

@Override

public void onStart(Intent intent) {

super.onStart(intent);

super.setUIContent(ResourceTable.Layout_page_listcontainer);

initListContainer();

}

private void initListContainer() {

ListContainer listContainer = (ListContainer) findComponentById(ResourceTable.Id_list_container);

List<SampleItem> list = getData();

SampleItemProvider sampleItemProvider = new SampleItemProvider(list, this);

listContainer.setItemProvider(sampleItemProvider);

}

private ArrayList<SampleItem> getData() {

ArrayList<SampleItem> list = new ArrayList<>();

for (int i = 0; i <= 8; i++) {

list.add(new SampleItem(“Item” + i));

}

return list;

}

listContainer在sampleItemProvider 初始化后修改数据。

private void initListContainer() {

ListContainer listContainer = (ListContainer) findComponentById(ResourceTable.Id_list_container);

List<SampleItem> list = getData();

SampleItemProvider sampleItemProvider = new SampleItemProvider(list, this);

listContainer.setItemProvider(sampleItemProvider);

list.add(new SampleItem(“Item” + sampleItemProvider.getCount()));

listContainer.setBindStateChangedListener(new Component.BindStateChangedListener() {

@Override

public void onComponentBoundToWindow(Component component) {

// ListContainer初始化时数据统一在provider中创建,不直接调用这个接口;

// 建议在onComponentBoundToWindow监听或者其他事件监听中调用。

sampleItemProvider.notifyDataChanged();

}

@Override

public void onComponentUnboundFromWindow(Component component) {}

});

}

图1 ListContainer的界面显示效果

ListContainer的常用接口

设置响应点击事件。

listContainer.setItemClickedListener((container, component, position, id) -> {

SampleItem item = (SampleItem) listContainer.getItemProvider().getItem(position);

new ToastDialog(this)

.setText(“you clicked:” + item.getName())

// Toast显示在界面中间

.setAlignment(LayoutAlignment.CENTER)

.show();

});图2 响应点击事件效果

设置响应长按事件。

listContainer.setItemLongClickedListener((container, component, position, id) -> {

SampleItem item = (SampleItem) listContainer.getItemProvider().getItem(position);

new ToastDialog(this)

.setText(“you long clicked:” + item.getName())

.setAlignment(LayoutAlignment.CENTER)

.show();

return false;

});图3 响应长按事件效果

ListContainer的样式设置

ListContainer的样式设置相关的接口如下:

属性Java方法作用
orientationsetOrientation(int orientation)设置布局方向
setContentStartOffSet(int startOffset)
setContentEndOffSet(int endOffset)
setContentOffSet(int startOffset, int endOffset)
设置列表容器的开始和结束偏移量
rebound_effectsetReboundEffect(boolean enabled)设置是否启用回弹效果
setReboundEffectParams(int overscrollPercent, float overscrollRate, 
int remainVisiblePercent)setReboundEffectParams
(ListContainer.ReboundEffectParams reboundEffectParams)
设置回弹效果参数
shader_colorsetShaderColor(Color color)设置着色器颜色
  • 设置ListContainer的布局方向:orientation设置为“horizontal”,表示横向布局;orientation设置为“vertical”,表示纵向布局。默认为纵向布局。在xml中设置:
    1. <ListContainer
    2. ohos:orientation=”horizontal”/>或在Java代码中设置:
    1. listContainer.setOrientation(Component.HORIZONTAL);图4 设置布局方向为horizontal的效果
  • 设置ListContainer的开始和结束偏移量。
    1. listContainer.setContentOffSet(32, 16);为了便于观察,分别在子布局和ListContainer布局中添加背景色。在item_sample.xml的根布局中添加背景色:
    1. <DirectionalLayout
    2. ohos:background_element=”#FAEBD7″>
    3. </DirectionalLayout>在ListContainer布局文件page_listcontainer.xml中添加背景色:
    1. <ListContainer
    2. ohos:background_element=”#FFDEAD”/>图5 设置列表容器的开始偏移量为32,结束偏移量为16效果
  • 设置回弹效果。在xml中设置:
    1. <ListContainer
    2. ohos:rebound_effect=”true”/>或在Java代码中设置
    1. listContainer.setReboundEffect(true);图6 回弹效果
    2. 在开启回弹效果后,可以调用setReboundEffectParams()方法调整回弹效果。
    1. listContainer.setReboundEffectParams(40, 0.6f, 20);
  • 设置着色器颜色。在xml中设置:
    1. <ListContainer
    2. ohos:shader_color=”#90EE90″/>或在Java代码中设置:
    1. listContainer.setShaderColor(new Color(Color.getIntColor(“#90EE90”)));图7 设置着色器效果

ListContainer性能优化

在适配ListContainer的数据时,无论是新创建的列表项实例,还是从缓存中获取到的,都需要调用方法findComponentById()获取所有子组件并进行数据填充,大量调用该方法,会损耗ListContainer的性能。比较好的解决方案是在创建列表项实例时进行调用,将获取到的所有子组件绑定到列表项的实例中,当从缓存中获取到列表项实例后,直接使用绑定的的子组件填充新数据。完整示例代码如下:

创建SettingItem.java,作为ListContainer的数据包装类。

public class SettingItem {

private int imageId;

private String settingName;

private boolean isChecked;

public SettingItem(int imageId, String settingName, boolean isChecked) {

this.imageId = imageId;

this.settingName = settingName;

this.isChecked = isChecked;

}

public int getImageId() {

return imageId;

}

public void setImageId(int imageId) {

this.imageId = imageId;

}

public String getSettingName() {

return settingName;

}

public void setSettingName(String settingName) {

this.settingName = settingName;

}

public boolean isChecked() {

return isChecked;

}

public void setChecked(boolean checked) {

isChecked = checked;

}

}

在layout目录下创建列表项布局layout_item_setting.xml。

<?xml version=”1.0″ encoding=”utf-8″?>

<DirectionalLayout

xmlns:ohos=”http://schemas.huawei.com/res/ohos”

ohos:height=”80vp”

ohos:width=”match_parent”

ohos:padding=”8vp”

ohos:orientation=”horizontal”>

<Image

ohos:id=”$+id:ima_setting”

ohos:height=”match_parent”

ohos:width=”0″

ohos:layout_alignment=”vertical_center”

ohos:weight=”2″>

</Image>

<Text

ohos:id=”$+id:text_setting”

ohos:height=”match_content”

ohos:width=”0″

ohos:padding=”4fp”

ohos:text_size=”20fp”

ohos:start_padding=”8vp”

ohos:end_padding=”8vp”

ohos:weight=”6″

ohos:layout_alignment=”vertical_center”/>

<Switch

ohos:id=”$+id:switch_setting”

ohos:height=”20vp”

ohos:width=”0vp”

ohos:weight=”1″

ohos:layout_alignment=”vertical_center”/>

</DirectionalLayout>

创建SettingProvider.java,用于保存子组件的数据信息。

// 请根据实际工程/包名引入

import com.example.myapplication.ResourceTable;

import ohos.aafwk.ability.AbilitySlice;

import ohos.agp.components.*;

import ohos.agp.components.element.ShapeElement;

import ohos.agp.components.element.StateElement;

import java.util.List;

public class SettingProvider extends BaseItemProvider{

// ListContainer的数据集合

private List<SettingItem> settingList;

private AbilitySlice slice;

public SettingProvider(List<SettingItem> list, AbilitySlice slice) {

this.settingList = list;

this.slice = slice;

}

// 用于保存列表项中的子组件信息

public class SettingHolder {

Image settingIma;

Text settingText;

Switch settingSwitch;

SettingHolder(Component component) {

settingIma = (Image) component.findComponentById(ResourceTable.Id_ima_setting);

settingText = (Text) component.findComponentById(ResourceTable.Id_text_setting);

settingSwitch = (Switch) component.findComponentById(ResourceTable.Id_switch_setting);

settingSwitch.setTrackElement(trackElementInit(

new ShapeElement(slice, ResourceTable.Graphic_track_on_element),

new ShapeElement(slice, ResourceTable.Graphic_track_off_element)));

settingSwitch.setThumbElement(thumbElementInit(

new ShapeElement(slice, ResourceTable.Graphic_thumb_on_element),

new ShapeElement(slice, ResourceTable.Graphic_thumb_off_element)));

}

private StateElement trackElementInit(ShapeElement on, ShapeElement off) {

StateElement trackElement = new StateElement();

trackElement.addState(new int[]{ComponentState.COMPONENT_STATE_CHECKED}, on);

trackElement.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, off);

return trackElement;

}

private StateElement thumbElementInit(ShapeElement on, ShapeElement off) {

StateElement thumbElement = new StateElement();

thumbElement.addState(new int[]{ComponentState.COMPONENT_STATE_CHECKED}, on);

thumbElement.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, off);

return thumbElement;

}

}

@Override

public int getCount() {

return settingList == null ? 0 : settingList.size();

}

@Override

public Object getItem(int position) {

if (settingList != null && position >= 0 && position < settingList.size()){

return settingList.get(position);

}

return null;

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public Component getComponent(int position, Component component, ComponentContainer componentContainer) {

final Component cpt;

SettingHolder holder;

SettingItem setting = settingList.get(position);

if (component == null) {

cpt = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_layout_item_setting, null, false);

holder = new SettingHolder(cpt);

// 将获取到的子组件信息绑定到列表项的实例中

cpt.setTag(holder);

} else {

cpt = component;

// 从缓存中获取到列表项实例后,直接使用绑定的子组件信息进行数据填充。

holder = (SettingHolder) cpt.getTag();

}

holder.settingIma.setPixelMap(setting.getImageId());

holder.settingText.setText(setting.getSettingName());

holder.settingSwitch.setChecked(setting.isChecked());

return cpt;

}

}其中使用到的graphic目录下的资源文件如下:thumb_off_element.xml:

<?xml version=”1.0″ encoding=”utf-8″?>

<shape xmlns:ohos=”http://schemas.huawei.com/res/ohos”

ohos:shape=”oval”>

<solid

ohos:color=”#FFFFFF”/>

<bounds

ohos:top=”0″

ohos:left=”0″

ohos:right=”20vp”

ohos:bottom=”20vp”/>

</shape>thumb_on_element.xml:

<?xml version=”1.0″ encoding=”utf-8″?>

<shape xmlns:ohos=”http://schemas.huawei.com/res/ohos”

ohos:shape=”oval”>

<solid

ohos:color=”#1E90FF”/>

<bounds

ohos:top=”0″

ohos:left=”0″

ohos:right=”20vp”

ohos:bottom=”20vp”/>

</shape>track_off_element.xml:

<?xml version=”1.0″ encoding=”utf-8″?>

<shape xmlns:ohos=”http://schemas.huawei.com/res/ohos”

ohos:shape=”rectangle”>

<solid

ohos:color=”#808080″/>

<corners

ohos:radius=”20vp”/>

</shape>track_on_element.xml:

<?xml version=”1.0″ encoding=”utf-8″?>

<shape xmlns:ohos=”http://schemas.huawei.com/res/ohos”

ohos:shape=”rectangle”>

<solid

ohos:color=”#87CEFA”/>

<corners

ohos:radius=”20vp”/>

</shape>

在layout目录下,AbilitySlice对应的布局文件page_listcontainer.xml文件中创建ListContainer。

<?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:padding=”8vp”

ohos:orientation=”vertical”>

<ListContainer

ohos:id=”$+id:list_container”

ohos:height=”match_parent”

ohos:width=”match_parent”/>

</DirectionalLayout>

ListContainer添加数据。

@Override

protected void onStart(Intent intent) {

super.onStart(intent);

setUIContent(ResourceTable.Layout_page_listcontainer);

ListContainer listContainer = (ListContainer) findComponentById(ResourceTable.Id_list_container);

SettingProvider provider = new SettingProvider(getData(), this);

listContainer.setItemProvider(provider);

}

private List<SettingItem> getData() {

ArrayList<SettingItem> data = new ArrayList<>();

for (int i = 0; i < 100; i++) {

data.add(new SettingItem(

ResourceTable.Media_icon,

“SettingName” + i,

i % 3 == 0

));

}

return data;

}

图8 效果如下:

0 0 投票数
文章评分
订阅评论
提醒
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x