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的使用方法

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

    <ListContainer    ohos:id="$+id:list_container"    ohos:height="200vp"    ohos:width="300vp"    ohos:layout_alignment="horizontal_center"/>
    
  2. 在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>
    
  3. 创建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;    }}
    
  4. 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 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;    }}
    
  5. 在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;    }
    

    图1 ListContainer的界面显示效果 img

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 响应点击事件效果 img

  • 设置响应长按事件。

    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 响应长按事件效果 img

ListContainer的样式设置

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

属性 Java方法 作用
orientation setOrientation(int orientation) 设置布局方向
- setContentStartOffSet(int startOffset)setContentEndOffSet(int endOffset)setContentOffSet(int startOffset, int endOffset) 设置列表容器的开始和结束偏移量
rebound_effect setReboundEffect(boolean enabled) 设置是否启用回弹效果
- setReboundEffectParams(int overscrollPercent, float overscrollRate, int remainVisiblePercent)setReboundEffectParams(ListContainer.ReboundEffectParams reboundEffectParams) 设置回弹效果参数
shader_color setShaderColor(Color color) 设置着色器颜色
  • 设置ListContainer的布局方向:orientation设置为“horizontal”,表示横向布局;orientation设置为“vertical”,表示纵向布局。默认为纵向布局。

    在xml中设置:

    <ListContainer    ...    ohos:orientation="horizontal"/>
    

    在Java代码中设置:

    listContainer.setOrientation(Component.HORIZONTAL);
    

    图4 设置布局方向为horizontal的效果 img

  • 设置ListContainer的开始和结束偏移量。

    listContainer.setContentOffSet(32, 16);
    

    为了便于观察,分别在子布局和ListContainer布局中添加背景色:

    在item_sample.xml的根布局中添加背景色。

    <DirectionalLayout    ...    ohos:background_element="#FAEBD7">    ...</DirectionalLayout>
    

    在ListContainer布局文件中添加背景色。

    <ListContainer    ...    ohos:background_element="#FFDEAD"/>
    

    图5 设置列表容器的开始偏移量为32,结束偏移量为16效果 img

  • 设置回弹效果。

    在xml中设置:

    <ListContainer    ...    ohos:rebound_effect="true"/>
    

    在Java代码中设置

    listContainer.setReboundEffect(true);
    

    图6 回弹效果 img

    在开启回弹效果后,可以调用setReboundEffectParams()方法调整回弹效果。

    listContainer.setReboundEffectParams(40, 0.6f, 20);
    
  • 设置着色器颜色。

    在xml中设置:

    <ListContainer    ...    ohos:shader_color="#90EE90"/>
    

    在Java代码中设置:

    listContainer.setShaderColor(new Color(Color.getIntColor("#90EE90")));
    

    图7 设置着色器效果 img

ListContainer性能优化

在适配ListContainer的数据时,无论是新创建的列表项实例,还是从缓存中获取到的,都需要调用方法findComponentById()获取所有子组件并进行数据填充,大量调用该方法,会损耗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_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

    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文件夹下,创建ListContainerSlice对应的布局文件layout_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添加数据

    public class ListContainerSlice extends AbilitySlice {       @Override    protected void onStart(Intent intent) {        super.onStart(intent);        setUIContent(ResourceTable.Layout_layout_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 效果如下: img

相关实例

针对ListContainer组件开发,有以下示例工程可供参考:

  • List

    本示例以长列表联系人为例,演示ListContainer 组件的基本使用方法。

results matching ""

    No results matching ""