鸿蒙学习-ListContainer

2021-04-13  本文已影响0人  学渣中的战斗渣

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

自有XML属性

rebound_effect:开启/关闭回弹效果,boolean类型

shader_color:着色器颜色,color类型

orientation:列表项排列方向

horizontal:表示水平方向列表。

vertical:表示垂直方向列表。

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();

});

ListContainer每一行可以为不同的数据,因此需要适配不同的数据结构,使其都能添加到ListContainer上。

创建SampleItemProvider.java,继承自BaseItemProvider。必须重写的方法如下:

getCount():返回填充的表项个数。

getItem(int position):根据position返回对应的数据。

getItemId(int position):返回某一项的id。

getComponent(int position, Component covertComponent,ComponentContainer componentContainer):根据position返回对应的界面组件。

设置响应长按事件。

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;

});

在适配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;

    }

}


上一篇下一篇

猜你喜欢

热点阅读