23. 布局

布局概述:

每种布局都根据自身特点提供LayoutConfig供子Component设定布局属性和参数,通过指定布局属性可以对子 Component在布局中的显示效果进行约束。例如:“width”、“height”是最基本的布局属性,它们指定了组件的大小。

组件和布局的包含关系:

布局可以理解为是一个容器,可以容纳组件和其他布局,并规定他们如何进行显示。组件在未被添加到布局中时,既无法显示也无法交互,因此一个用户界面至少包含一个布局。
Java UI框架提供了一些标准布局功能的容器,它们继承自ComponentContainer,一般以“Layout”结尾,如 DirectionalLayout、DependentLayout等。


组件树:

在一个界面中,最外层是一定是布局,在布局里面可以有组件,也可以有其他布局。所以布局可以理解为是多个组件形成的那个整体。

线性布局:DirectionalLayout

权重

也是一种百分比布局。

先计算父布局中,可利用空间之和:

父布局可分配区域=父布局长度或者宽度-所有固定长度或者宽度大小;

再计算百分比。
 

代码

<?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:orientation="vertical">

    <Button
        ohos:height="0vp"
        ohos:width="100vp"
        ohos:text="点我1"
        ohos:text_size="35fp"
        ohos:text_color="#FFFFFF"
        ohos:text_alignment="center"
        ohos:background_element="#21A8FD"
        ohos:weight="2"/>

    <Button
        ohos:height="0vp"
        ohos:width="100vp"
        ohos:text="点我2"
        ohos:text_size="35fp"
        ohos:text_color="#FFFFFF"
        ohos:text_alignment="center"
        ohos:background_element="#FF0000"
        ohos:weight="1"/>

    <Image
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:image_src="$media:girl"/>

</DirectionalLayout>

相对布局:DependentLayout

核心:

找基准位置(和属性alignment相关,center,horizontal_center,vertical_center等)

在相对布局中,组件的位置是相对其他组件而言的

代码:

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

    <Text
        ohos:id="$+id:text1"
        ohos:height="100vp"
        ohos:width="100vp"
        ohos:background_element="#21A8FD"
        ohos:text="text1"
        ohos:text_size="20fp"/>

    <Text
        ohos:id="$+id:text2"
        ohos:height="100vp"
        ohos:width="100vp"
        ohos:background_element="#FF0000"
        ohos:right_of="$id:text1"
        ohos:text="text2"
        ohos:text_size="20fp"/>

    <Text
        ohos:height="100vp"
        ohos:width="100vp"
        ohos:background_element="#00ff00"
        ohos:below="$id:text2"
        ohos:left_margin="100vp"
        ohos:text="text3"
        ohos:text_size="20fp"/>

</DependentLayout>

格子布局:TableLayout

说明:

行数和列数两个属性。

如果塞入元素过多,行数自动失效,再加一行。

对齐方式:alignment_type

值:align_contents(页边距对齐)(Margin alignment)

align_edges(边界对齐)(boundary alignment)

页边距对齐,是按照上一个组件的相对边界

边界对齐,是跟上一个组件对齐

   其他布局:StackLayout(堆叠布局)、 AdaptiveBoxLayout(自适应盒子布局)

代码:

<?xml version="1.0" encoding="utf-8"?>
<TableLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:orientation="vertical"
    ohos:row_count="3"
    ohos:column_count="3"
    ohos:alignment_type="align_edges">

    <Text
        ohos:height="50vp"
        ohos:width="50vp"
        ohos:background_element="#FF0000"
        ohos:text="1"
        ohos:text_size="35fp"
        ohos:text_color="#000000"
        ohos:left_margin="50vp"
        ohos:text_alignment="center"/>

    <Text
        ohos:height="50vp"
        ohos:width="50vp"
        ohos:background_element="#00FF00"
        ohos:text="2"
        ohos:text_size="35fp"
        ohos:text_color="#000000"
        ohos:text_alignment="center"/>

    <Text
        ohos:height="50vp"
        ohos:width="50vp"
        ohos:background_element="#0000FF"
        ohos:text="3"
        ohos:text_size="35fp"
        ohos:text_color="#000000"
        ohos:text_alignment="center"/>

    <Text
        ohos:height="50vp"
        ohos:width="50vp"
        ohos:background_element="#FFFF00"
        ohos:text="4"
        ohos:text_size="35fp"
        ohos:text_color="#000000"
        ohos:text_alignment="center"/>

    <Text
        ohos:height="50vp"
        ohos:width="50vp"
        ohos:background_element="#FF00FF"
        ohos:text="5"
        ohos:text_size="35fp"
        ohos:text_color="#000000"
        ohos:text_alignment="center"/>

    <Text
        ohos:height="50vp"
        ohos:width="50vp"
        ohos:background_element="#FF0000"
        ohos:text="6"
        ohos:text_size="35fp"
        ohos:text_color="#000000"
        ohos:text_alignment="center"/>

    <Text
        ohos:height="50vp"
        ohos:width="50vp"
        ohos:background_element="#00FF00"
        ohos:text="7"
        ohos:text_size="35fp"
        ohos:text_color="#000000"
        ohos:text_alignment="center"/>

    <Text
        ohos:height="50vp"
        ohos:width="50vp"
        ohos:background_element="#0000FF"
        ohos:text="8"
        ohos:text_size="35fp"
        ohos:text_color="#000000"
        ohos:text_alignment="center"/>

    <Text
        ohos:height="50vp"
        ohos:width="50vp"
        ohos:background_element="#FFFF00"
        ohos:text="9"
        ohos:text_size="35fp"
        ohos:text_color="#000000"
        ohos:text_alignment="center"/>

    <Text
        ohos:height="50vp"
        ohos:width="50vp"
        ohos:background_element="#FF0000"
        ohos:text="10"
        ohos:text_size="35fp"
        ohos:text_color="#000000"
        ohos:text_alignment="center"/>

</TableLayout>

列表容器组件:ListContainer

ListContainer是一个列表容器类组件。在这里的每一行,我们都可以看做是一个item。如下图所示,包裹了所有 item的红色的容器,就是ListContainer。

注意细节:
1 每一行其实就是一个独立的item。

2 在屏幕的上面和下面,还有很多没有展示出来的item。 当我们用手指往上滑动的时候,就可以到下面的item。 当我们用手指往下滑动的时候,就可以到上面的item。 只不过划出屏幕的item会被销毁,而没有划入屏幕的item 还没有创建出来。

3 如果item过多,在内存会有垃圾。

实现步骤:

1. 给item去指定一个布局xml文件

2. 书写一个javabean类表示item

3. 写一个适配器类去管理item

4. 将适配器交给ListContainer

代码:

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:orientation="vertical"
    ohos:alignment="center">

    <ListContainer
        ohos:id="$+id:listcontainer"
        ohos:height="match_parent"
        ohos:width="match_parent"
        ohos:layout_alignment="horizontal_center"/>

</DirectionalLayout>

itemview.xml

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

    <Text
        ohos:id="$+id:text"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="00:00"
        ohos:text_size="20fp"/>

</DirectionalLayout>

Item.java

package com.example.myapplication.domain;

public class Item {
    //记录的值就是赋值给item里的text
    private String text;

    public Item() {
    }

    public Item(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

ItemProvider.java

public class ItemProvider extends BaseItemProvider {

    //集合
    //集合中就装了所有的item的对象
   private ArrayList<Item> list;
   private AbilitySlice as;

    public ItemProvider(ArrayList<Item> list, AbilitySlice as) {
        this.list = list;
        this.as = as;
    }

    public ArrayList<Item> getList() {
        return list;
    }

    public void setList(ArrayList<Item> list) {
        this.list = list;
    }

    public AbilitySlice getAs() {
        return as;
    }

    public void setAs(AbilitySlice as) {
        this.as = as;
    }

    //总数据的个数
    //多少个item
    @Override
    public int getCount() {
        return list.size();
    }


    //i表示索引
    //根据索引返回数据
    @Override
    public Object getItem(int i) {
        if (list != null && i >= 0 && i < list.size()){
            return list.get(i);
        }
        return null;
    }

    //返回某一项的ID
    @Override
    public long getItemId(int i) {
        return i;
    }


    //返回item中要加载的布局对象
    //参数一:当前要加载哪一行的的item(item的索引)
    @Override
    public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
        //获取每一个item里面的布局对象
        DirectionalLayout dl = (DirectionalLayout) LayoutScatter.getInstance(as).parse(ResourceTable.Layout_itemview, null, false);
        //获取每一个item里的数据
        Item item = list.get(i);
        //把数据加载到布局里的text中
        Text text = (Text) dl.findComponentById(ResourceTable.Id_text);
        text.setText(item.getText());

        //当上面的代码执行完毕时就会获取到一个有数据的布局对象
        //这时,只要把布局对象dl返回出去就可以了
        //在item中,最外层的就是这个dl布局对象
        return dl;
    }
}

MainAbilitySlice.java

public class MainAbilitySlice extends AbilitySlice {
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);

        //找到ListContainer
        ListContainer listcontainer = (ListContainer) findComponentById(ResourceTable.Id_listcontainer);
        //创建集合并给集合添加数据
        ArrayList<Item> datasList = getData();
        //创建一个item的管理员对象(适配器对象)
        //并把要展示的所有数据和要加载的页面传递过去
        ItemProvider itemprovider = new ItemProvider(datasList,this);

        //把适配器交给列表容器中
        listcontainer.setItemProvider(itemprovider);
    }


    public ArrayList<Item> getData(){
        ArrayList<Item> list = new ArrayList<>();
        for (int i = 0;i < 100;i++){
            list.add(new Item("item"+i));
        }
        return list;
    }


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

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

内存优化:

  1. 加载一个item,getComponent方法就要被调用一次。

  2. 假设屏幕中最多显示12个item,此时第13个item还没有在界面中显示出来。但是,ListContainer也会进行预加载。 预加载的好处:避免卡顿。

  3. 当item划出屏幕的时候,就会被销毁。当页面再次往下滑动的时候,会再次调用getComponent方法,加载本地xml文件,创建一个新的item布局对象。当item加载过多,内存中的垃圾就会过多,所以我们要优化。

  4. 优化的核心:让划出屏幕的item不销毁,而是继续复用

其它布局

绝对布局(PositionLayout)

可以指定组件的具体位置。

自适应布局(AdaptiveBoxLayout)

指定一行的范围。

屏幕范围小,每行就展示一个,屏幕范围大,就展示多个

底层还不是太稳定。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值