1.常见布局和常见组件

组件:

屏幕展示出来的元素,都称之为组件。比如华为已经提供的:文本,图片,进度条,输入框等。

顶级父类:Component

布局:

组件的展示方式。比如:线性布局,相对布局,绝对布局,格子布局等。

顶级父类:

ComponentContainer。理解为组件容器。

        布局一般以“Layout”结尾,如DirectionalLayoutDependentLayout等。不同的布局中,组件的展示方式是不一样的,比如线性布局,就是从上往下,或者从左往右依次摆放内部组件的。比如格子布局,就是nn列的格子。

注意点:

组件在未被添加到布局中时,既无法显示也无法交互,因此一个用户界面至少包含一个布局。

2.常见组件

组件分类:

  • 显示类组件 只负责数据展示的,无法跟用户交互,比如展示文本的组件,展示图片的组件。
  • 交互类组件 可以跟用户交互的,比如用户可以点击的按钮组件,用户可以输入的文本框组件。
  • 布局类组件 刚刚讲解的布局其实也是一种比较特殊的组件。

3.显示类组件

        文本Text、图片ImageCommonDialog普通弹框组件、ToastDialog信息提示组件、时钟Clock、定时器TickTimer、进度条ProgressBar

3.1Text文本组件

概述:

        文本(Text)是用来显示字符串的组件,在界面上显示为一块文本区域。仅仅作为展示数据使用,用户不能在App中修改文本组件中的内容。

        Text组件是最基本的组件,后面还会学习他的子类组件,比如ButtonTextField都是从这个类衍生而来的。

常见的属性:

        这些属性不用去背,用着用着就熟了,想要对文本进行一个设置,如果忘记属性,可以直接到笔记中找,或者到华为开发者文档中找。

地址:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V3/ui-java-component-text-000000105072953-V3

单独讲解的基本属性:

宽高大小 match_parent

match_content

具体的长度单位:pxvpfp

dp(安卓里面的单位,跟鸿蒙中的vp是一样的)

vp(虚拟像素)长度单位。

fp字体大小单位。不缩放的情况下fp=vp

(扩展点)如果有缩放。 1fp = 1vp * 缩放比例。

如果不写单位,默认单位是px

颜色属性:RGB光学三原色

书写形式:可以直接写单词。red

可以写十六进制的三原色。 #112233

可以写透明度。 #FF112233

可以写简写 #123(简写的时候不能加透明度)

其他写法(不利于阅读): #5901(前面补0,满足6位,不利于阅读)

间距:内边距,外边距。

代码示例:

常见属性

<Text

    ohos:id="$+id:text"

    ohos:width="match_content"

    ohos:height="match_content"

    ohos:text="Text"

    ohos:background_element="$graphic:color_gray_element"

    />


其他属性使用方式:

字体大小

ohos:text_size="28fp"

字体颜色

ohos:text_color="blue"

Text组件的左外边距

ohos:left_margin="15vp"

Text组件的下外边距

ohos:bottom_margin="15vp"

Text组件和内部文本的右内边距

ohos:right_padding="15vp"

Text组件和内部文本的左内边距

ohos:left_padding="15vp"


设置字体风格

斜体

ohos:italic="true"

字重(就是文字的粗细)

ohos:text_weight="700"

字体

ohos:text_font="serif"



设置文本对齐方式


ohos:text_alignment="horizontal_center|bottom"



设置文本换行

ohos:multiple_lines="true"

最大显示行数

ohos:max_text_lines="2"

练习1:编写登录页面

最终效果如下:

代码示例:
<?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:background_element="#F2F2F2"
            ohos:orientation="vertical"
            >


  <Text
    ohos:height="50vp"
    ohos:width="319vp"
    ohos:background_element="#FFFFFF"
    ohos:layout_alignment="horizontal_center"
    ohos:text="请输入手机号"
    ohos:text_alignment="center"
    ohos:text_color="#999999"
    ohos:text_size="17fp"
    ohos:top_margin="100vp"
    />


  <Text
    ohos:height="50vp"
    ohos:width="319vp"
    ohos:background_element="#FFFFFF"
    ohos:layout_alignment="horizontal_center"
    ohos:text="请输入密码"
    ohos:text_alignment="center"
    ohos:text_color="#999999"
    ohos:text_size="17fp"
    ohos:top_margin="10vp"/>

  <Text
    ohos:height="match_content"
    ohos:width="match_content"
    ohos:layout_alignment="right"
    ohos:right_margin="20vp"
    ohos:text="忘记密码了?"
    ohos:text_color="#979797"
    ohos:text_size="17fp"
    ohos:top_margin="13vp"/>

  <Button
    ohos:height="47vp"
    ohos:width="319vp"
    ohos:background_element="#21a8fd"
    ohos:layout_alignment="horizontal_center"
    ohos:text="登录"
    ohos:text_alignment="center"
    ohos:text_color="#FEFEFE"
    ohos:text_size="24vp"
    ohos:top_margin="77vp"/>

  <Button
    ohos:height="47vp"
    ohos:width="319vp"
    ohos:background_element="#21a8fd"
    ohos:layout_alignment="horizontal_center"
    ohos:text="注册"
    ohos:text_alignment="center"
    ohos:text_color="#FEFEFE"
    ohos:text_size="24vp"
    ohos:top_margin="13vp"/>

</DirectionalLayout>

练习2:修改密码页面

最终效果如下:

练习3:文本框展示大段文字

省略文字和跑马灯效果
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:alignment="center"
    ohos:orientation="vertical"
>

<Text
    ohos:id="$+id:text1"
    ohos:height="100vp"
    ohos:width="200vp"
    ohos:background_element="#55121212"
    ohos:text="小明:你说我这穷日子过到啥时侯是个头啊?小红:那得看你能活多久了。"
    ohos:text_size="40vp"



    //截取模式
    //ellipsis_at_start:前面内容省略
    //ellipsis_at_end:后面内容省略
    //ellipsis_at_middle:中间内容省略,但是需要组件足够宽
    //none:不做任何处理
    //auto_scrolling:滚动处理,(需要开启滚动)
    ohos:truncation_mode="none"


    //滚动次数
    //整数表示滚动次数
    //unlimited:没有次数限制
    ohos:auto_scrolling_count="unlimited"


    //滚动持续时间:单位是毫秒
    auto_scrolling_duration="1000"
/>
</DirectionalLayout>


Java代码:
    Text text = (Text) findComponentById(ResourceTable.Id_text1);


    text.setClickedListener(component ->{
      Text t = (Text) component;
      //开启跑马灯
      t.startAutoScrolling();
      }
    );

3.2Image图片组件

概述:

图片(Image)是用来显示图片的组件。

常见的属性:

当然也有id,长、宽、高等。

具体可以参考华为开发手册(组件的通用属性):

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-component-common-xml-0000001138483639

比较重要的属性:

单独讲解的基本属性:

image_src:如何在xml中使用本地资源文件。

顺便讲一下如何在代码中使用本地资源文件。

基本用法:

<Image
    ohos:height="100vp"
    ohos:width="100vp"
    ohos:image_src="$media:all"
    ohos:background_element="#00ff00"/>

相关方法:

图片剪切显示:

代码中:可以用setClipGravity方法

xml文件中:可以用clip_alignment属性

  • 上、下、左、右、居中
  • 表示分别按照上、下、左、右、中间部位进行剪切。
图片缩放显示:

代码中:可以用setScaleMode方法

xml文件中:可以用scale_mode属性

inside:表示将原图按比例缩放到与Image相同或更小的尺寸,并居中显示。 有可能不会填充组件

  • center:表示不缩放,按Image大小显示原图中间部分。
  • stretch:表示将原图缩放到与Image大小一致。 拉伸。将组件填充。
  • clip_center:表示将原图按比例缩放到与Image相同或更大的尺寸,并居中显示。超过组件的部分被剪切掉。

  • zoom_center:表示原图按照比例缩放到与Image最窄边一致,并居中显示。

  • zoom_end:表示原图按照比例缩放到与Image最窄边一致,并靠结束端显示。

  • zoom_start:表示原图按照比例缩放到与Image最窄边一致,并靠起始端显示。

注意:

        一般来讲在设置的时候会跟图片保持一致,否则图片会失真。如果业务需求要调整图片大小,那么我们是找美工重新做一张图,而不是代码拉伸或者剪切。

缩放、剪切用法:
<Image
    ohos:height="100vp"
    ohos:width="100vp"
    ohos:image_src="$media:all"
    ohos:background_element="#00ff00"
    缩放
    ohos:scale_mode="zoom_center"
    剪切
    ohos:clip_alignment="top"/>

练习: 1,点击按钮随机出现妹子的信息和介绍

代码示例:
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">

<Image
    ohos:id="$+id:img"
    ohos:height="match_content"
    ohos:width="match_content"
    ohos:image_src="$media:girl1"/>

    <Text
        ohos:id="$+id:name"
        ohos:height="50vp"
        ohos:width="150vp"
        ohos:text="姓名:王美花"
        ohos:text_size="20fp"/>

    <Text
        ohos:id="$+id:age"
        ohos:height="50vp"
        ohos:width="150vp"
        ohos:text="年龄:29"
        ohos:text_size="20fp"/>
    
    <Text
        ohos:id="$+id:address"
        ohos:height="50vp"
        ohos:width="150vp"
        ohos:text="地址:南京"
        ohos:text_size="20fp"/>

    <Button
        ohos:id="$+id:next"
        ohos:height="50vp"
        ohos:width="150vp"
        ohos:background_element="#92D050"
        ohos:text="下一个"
        ohos:text_size="20fp"
        ohos:text_color="#FFFFFF"/>

    <Button
        ohos:id="$+id:get"
        ohos:height="50vp"
        ohos:width="150vp"
        ohos:background_element="#92D050"
        ohos:text="获取联系方式"
        ohos:text_size="20fp"
        ohos:text_color="#FFFFFF"
        ohos:top_margin="10vp"
        />


</DirectionalLayout>



java文件:
package com.example.imageapplication.domain;

public class GirlFriend {
    //照片
    private int photoID;
    //姓名
    private String name;
    //年龄
    private int age;
    //地址
    private String address
    //空参 + 全参
    //alt + insert
    //alt + Fn + insert
    public GirlFriend() {
    }

    public GirlFriend(int photoID, String name, int age, String address) {
      this.photoID = photoID;
      this.name = name;
      this.age = age;
      this.address = address;
    }

    //get set
    
    public int getPhotoID() {
      return photoID;
    }

    public void setPhotoID(int photoID) {
      this.photoID = photoID;
    }

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public int getAge() {
      return age;
    }

    public void setAge(int age) {
      this.age = age;
    }

    public String getAddress() {
      return address;
    }
public void setAddress(String address) {
this.address = address;
}
}
java文件:

public class GirlFriend {
    //照片
    private int photoID;
    //姓名
    private String name;
    //年龄
    private int age;
    //地址
    private String address;

    //空参 + 全参
    //alt + insert
    //alt + Fn + insert
    public GirlFriend() {
    }

    public GirlFriend(int photoID, String name, int age, String address) {
      this.photoID = photoID;
      this.name = name;
      this.age = age;
      this.address = address;
    }

    //get set


    public int getPhotoID() {
      return photoID;
    }

    public void setPhotoID(int photoID) {
      this.photoID = photoID;
    }

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public int getAge() {
      return age;
    }

    public void setAge(int age) {
      this.age = age;
    }

    public String getAddress() {
      return address;
    }

    public void setAddress(String address) {
      this.address = address;
    }
}




public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
    Image img;
    Text name;
    Text age;
    Text address;
    Button next;
    Button get;
    ArrayList<GirlFriend> list = new ArrayList<>();

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

      //1.找到组件对象
      img = (Image) findComponentById(ResourceTable.Id_img);
      name = (Text) findComponentById(ResourceTable.Id_name);
      age = (Text) findComponentById(ResourceTable.Id_age);
      address = (Text) findComponentById(ResourceTable.Id_address);
      next = (Button) findComponentById(ResourceTable.Id_next);
      get = (Button) findComponentById(ResourceTable.Id_get);

      //2.创建一个集合装9个女朋友对象
      //添加9个对象
      //在以后当我们学习了跟服务器交互之后,这些数据都是从服务器获取的。
      list.add(new GirlFriend(ResourceTable.Media_girl1, "王美花1", 29, "南京"));
      list.add(new GirlFriend(ResourceTable.Media_girl2, "王美花2", 30, "南京"));
      list.add(new GirlFriend(ResourceTable.Media_girl3, "王美花3", 31, "南京"));
      list.add(new GirlFriend(ResourceTable.Media_girl4, "王美花4", 35, "南京"));
      list.add(new GirlFriend(ResourceTable.Media_girl5, "王美花5", 21, "南京"));
      list.add(new GirlFriend(ResourceTable.Media_girl6, "王美花6", 20, "南京"));
      list.add(new GirlFriend(ResourceTable.Media_girl7, "王美花7", 35, "南京"));
      list.add(new GirlFriend(ResourceTable.Media_girl8, "王美花8", 25, "南京"));
      list.add(new GirlFriend(ResourceTable.Media_girl9, "王美花9", 23, "南京"));

      //3.给按钮添加点击事件
      next.setClickedListener(this);
      get.setClickedListener(this);

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

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

    Random r = new Random();
    @Override
    public void onClick(Component component) {
      if (component == next) {
        //点击的是下一个 --- 换一个妹子的信息
        //从集合中获取一个随机的妹子信息

        //获取一个随机索引、
        int randomIndex = r.nextInt(list.size());
        //通过随机索引获取随机的小姐姐信息
        GirlFriend gf = list.get(randomIndex);
        //把随机出来的信息设置到界面当中
        img.setImageAndDecodeBounds(gf.getPhotoID());
        name.setText("姓名:" + gf.getName());
        age.setText("年龄:" + gf.getAge());
        address.setText("地址:" + gf.getAddress());
      } else if (component == get) {
        //点击的是获取联系方式
        //等以后学习了后面的知识,就可以跳转界面让用户充值
        //充值成功之后再获取小姐姐的联系方式
      }
    }
}

3.3CommonDialog普通弹框组件

使用默认布局的基本用法:

//把普通弹框弹出来就可以了
//1.创建弹框的对象
//this:当前弹框是哪展示在当前的界面中的。
CommonDialog cd = new CommonDialog(this);
//2.因为弹框里面是有默认布局的
//设置标题
cd.setTitleText("系统定位服务已关闭");
//设置内容
cd.setContentText("请打开定位服务,以便司机师傅能够准确接您上车");
//自动关闭
cd.setAutoClosable(true);

//设置按钮
//参数一:按钮的索引 0 1 2
//参数二:按钮上的文字

//参数三:点击了按钮之后能做什么

cd.setButton(0, "设置", new IDialog.ClickedListener() {
  @Override
  public void onClick(IDialog iDialog, int i) {
    //写上点击了设置之后,要做的事情。
    //如果点击之后我不需要做任何事情,在第三个参数中传递null就可以了。
  }
});

cd.setButton(1, "取消", new IDialog.ClickedListener() {
  @Override
  public void onClick(IDialog iDialog, int i) {
    //销毁弹框
    cd.destroy();
  }
});

//把弹框显示出来
cd.show();
}

自定义弹框布局:

编写思路:

弹框里面也是可以展示各种内容的,所以可以给弹框写一个xml布局文件:

文件名:

toast_layout_confirm.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="vertical">

    <Text
      ohos:id="$+id:message"
      ohos:height="match_content"
      ohos:width="match_content"
      ohos:text_size="40fp"/>

    <Button
      ohos:id="$+id:submit"
      ohos:height="match_content"
      ohos:width="match_content"
      ohos:text="确定"
      ohos:text_size="40fp"
      ohos:background_element="#21a896"/>

    <Button
      ohos:id="$+id:cancel"
      ohos:height="match_content"
      ohos:width="match_content"
      ohos:text="取消"
      ohos:text_size="40fp"
      ohos:background_element="#0021D9"
      ohos:top_margin="10vp"
      />

</DirectionalLayout>

java类:

//把弹框展示出来
//创建一个弹框对象
CommonDialog cd = new CommonDialog(this);
//大小是默认包裹内容的。
//弹框默认是居中放置
//弹框默认是透明的
//弹框默认是直角,可以把直角设置为圆角
cd.setCornerRadius(15);


//把messagedislog的xml文件加载到内存当中。交给弹框并展示出来。

//加载xml文件并获得一个布局对象
//parse方法:加载一个xml文件,返回一个布局对象。
//参数一:要加载的xml文件
//参数二:该xml文件是否跟其他xml文件有关。如果无关是独立的,就写null就可以了
//参数三:如果文件是独立的,那么直接写false
DirectionalLayout dl = (DirectionalLayout)
LayoutScatter.getInstance(this).parse(ResourceTable.Layout_messagedialog, null, false);
//要给布局里面的文本和按钮设置事件或者修改内容
//此时需要用dl去调用,表示获取的是dl这个布局里面的组件。
Text title = (Text) dl.findComponentById(ResourceTable.Id_message);
Button submit = (Button) dl.findComponentById(ResourceTable.Id_submit);
Button cancel = (Button) dl.findComponentById(ResourceTable.Id_cancel);

//title给标题设置内容
title.setText(msg);

//还需要给两个按钮添加单击事件
submit.setClickedListener(new Component.ClickedListener() {
  @Override
  public void onClick(Component component) {
    title.setText("点击了确定按钮");
  }
});

//取消按钮也要添加点击事件
cancel.setClickedListener(new Component.ClickedListener() {

  @Override
  public void onClick(Component component) {
    //当点击了取消按钮之后,把弹框给关闭
    cd.destroy();
  }
});

//此时布局对象跟弹框还没有任何关系
//我还需要把布局对象交给弹框才可以
cd.setContentCustomComponent(dl);

//让弹框展示出来
cd.show();
注意点:

如果需要更复杂的弹框,只要丰富xml文件中的组件即可。

抽取工具类:

public class MyDialog {

  public static void showDialog(Context context,String msg){
    //把弹框展示出来
    //创建一个弹框对象
    CommonDialog cd = new CommonDialog(context);
    //大小是默认包裹内容的。
    //弹框默认是居中放置
    //弹框默认是透明的
    //弹框默认是直角,可以把直角设置为圆角
    cd.setCornerRadius(15);


    //把messagedislog的xml文件加载到内存当中。交给弹框并展示出来。

    //加载xml文件并获得一个布局对象
    //parse方法:加载一个xml文件,返回一个布局对象。
    //参数一:要加载的xml文件
    //参数二:该xml文件是否跟其他xml文件有关。如果无关是独立的,就写null就可以了
    //参数三:如果文件是独立的,那么直接写false
    DirectionalLayout dl = (DirectionalLayout)
  LayoutScatter.getInstance(context).parse(ResourceTable.Layout_messagedialog, null, false);
    //要给布局里面的文本和按钮设置事件或者修改内容
    //此时需要用dl去调用,表示获取的是dl这个布局里面的组件。
    Text title = (Text) dl.findComponentById(ResourceTable.Id_message);
    Button submit = (Button) dl.findComponentById(ResourceTable.Id_submit);
    Button cancel = (Button) dl.findComponentById(ResourceTable.Id_cancel);

    //title给标题设置内容
    title.setText(msg);
    
    //还需要给两个按钮添加单击事件
    submit.setClickedListener(new Component.ClickedListener() {

      @Override
      public void onClick(Component component) {
        title.setText("点击了确定按钮");
      }
    });

    //取消按钮也要添加点击事件
    cancel.setClickedListener(new Component.ClickedListener() {
      @Override
      public void onClick(Component component) {
        //当点击了取消按钮之后,把弹框给关闭
        cd.destroy();
      }
    });

    //此时布局对象跟弹框还没有任何关系
    //我还需要把布局对象交给弹框才可以
    cd.setContentCustomComponent(dl);
    
    //让弹框展示出来
    cd.show();
  }
}

3.4ToastDialog信息提示组件

也叫做吐司弹框。其实就是一个小提示而已。

ToastDialogCommonDialog的子类,所以具备CommonDialog相关的特性。

也包含了标题,内容还有选择按钮。

但是一般来讲,吐司弹框我们只用中间的内容部分,因为他出现的意义就是为了提示信息的。

基本使用:

ToastDialog t = new ToastDialog(this);
t.setText("要显示的内容")
t.setAlignment(LayoutAlignment.CENTER);
t.show();

相关设置:

ToastDialog toastDialog = new ToastDialog(this);
//设置的大小
//如果不写,默认包裹内容
toastDialog.setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT,
DirectionalLayout.LayoutConfig.MATCH_CONTENT);
//设置持续时间

//如果不写,默认2秒
toastDialog.setDuration(2000);
//设置自动关闭
//如果不写,就是自动关闭
toastDialog.setAutoClosable(true);
//设置位置
//如果不写,默认居中
toastDialog.setAlignment(LayoutAlignment.CENTER);
//设置提示信息内容
toastDialog.setText("要显示的内容");
//让吐司展示出来
toastDialog.show();

自定义布局和抽取工具类:

        一般会把吐司提示信息封装成一个工具类,用到的时候再调用,这样可以自定义吐司里面的文本的样式。

        在后面我们会学习美化组件,让吐司跟咱们在玩app的时候看到的弹框保持一致。

public class MyToastUtils {
  public static void showDialog(Context context,String msg){
    //1.加载xml布局文件
    DirectionalLayout dl = (DirectionalLayout)
  LayoutScatter.getInstance(context).parse(ResourceTable.Layout_mytoast, null, false);
    //创建吐司弹框的对象
    ToastDialog td = new ToastDialog(context);
    //设置吐司的大小

  td.setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT,DirectionalLayout.LayoutConfig.MATCH_CONTENT);
    //设置出现的时间
    td.setDuration(2000);
    //设置自动关闭
    td.setAutoClosable(true);
    //设置对齐方式
    td.setAlignment(LayoutAlignment.CENTER);
    //给吐司弹框设置要展示的文本内容
    td.setText(msg);
    //让吐司弹框出现
    td.show();
  }
}
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐