第9章 HarmonyOs图解 Java UI 开发

HarmonyOS 学习系统 | 阶段二:进阶实战期
建议学习时长:2-3 周


学习目标

序号 能力
1 理解 Java UI 框架的组件树结构和命令式编程模型
2 掌握常用 UI 组件(Text、Button、Image、TextField 等)的使用
3 熟练使用四种布局(Directional、Dependent、Stack、Table)
4 能独立实现完整的 UI 界面(如登录页面)

核心图解

Java UI vs JS UI 对比图


内容讲解

9.1 Java UI 框架

Java UI 开发就像搭积木:

  • Component(组件) = 各种形状的积木块(Text=文字积木、Button=按钮积木、Image=图片积木)
  • ComponentContainer(容器) = 积木底板——用来放积木的板子
  • LayoutConfig(布局配置) = 积木的摆放规则——这块放左边、那块放右边
  • 组件树 = 搭好的积木城堡——有层级关系的整体结构
  • DirectionalLayout = 单向排列架——积木只能横排或竖排
  • DependentLayout = 自由摆放桌——积木可以相对于其他积木自由放置
  • StackLayout = 堆叠桌——积木一层叠一层

Java UI 框架提供了两类核心对象:Component(组件基类)和 ComponentContainer(容器基类)。所有 UI 操作都应在主线程进行。

两种创建 UI 的方式

  1. XML 声明布局:在 resources/base/layout/ 目录下创建 XML 文件,通过 setUIContent(ResourceTable.Layout_xxx) 加载
  2. Java 代码创建:在 AbilitySlice 中直接通过 new DirectionalLayout() 等创建组件

9.2 常用组件

组件 用途 常用方法
Text 显示文本 setText(), setTextColor(), setTextSize(), setTruncationMode()
Button 点击按钮 setClickedListener(), setText()
Image 显示图片 setPixelMap(), setScaleMode(), setImageAndScaleMode()
TextField 文本输入框 getText(), setText(), setHint(), setInputType()
Checkbox 复选框 setChecked(), setCheckedStateChangedListener()
RadioButton / RadioContainer 单选按钮 setMarked(), setRadioStateChangedListener()
Switch 开关 setChecked(), setOnStateChangedListener()
ProgressBar 进度条 setProgressValue(), setMaxValue(), setViceProgressValue()
RoundProgressBar 圆形进度条 同上 + setViceProgress()
ListContainer 列表 setItemProvider(), setOnItemClickListener()
TabList / Tab 选项卡 setTabSelectedListener(), selectTab()
ScrollView 滚动视图 包裹子组件实现滚动
PageSlider 滑动翻页 setProvider(), setPageChangedListener()
组件 ID 查找

在 AbilitySlice 中通过 ID 查找组件:

Text text = (Text) findComponentById(ResourceTable.Id_text_helloworld);
text.setText("新的文本内容");

注意:必须使用 ResourceTable.Id_xxx 常量引用,不能直接使用字符串。

按钮点击事件
Button button = (Button) findComponentById(ResourceTable.Id_btn_login);
button.setClickedListener(new Component.ClickedListener() {
    @Override
    public void onClick(Component component) {
        // 处理点击逻辑
        new ToastDialog(getContext())
            .setText("登录成功")
            .show();
    }
});

9.3 常用布局

布局 排列方式 生活类比 适用场景
DirectionalLayout 水平或垂直单向排列 排队:要么横排要么竖排 表单、列表项、工具栏
DependentLayout 相对于其他组件定位 自由摆放:你想放哪就放哪 复杂页面、登录界面
StackLayout 组件堆叠 叠罗汉:一层叠一层 悬浮按钮、图片叠加文字
TableLayout 表格行列布局 棋盘:按行列排列 计算器、网格展示
DirectionalLayout 示例(XML)
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:width="match_parent"
    ohos:height="match_parent"
    ohos:orientation="vertical">

    <Text
        ohos:width="match_parent"
        ohos:height="50vp"
        ohos:text="用户名"
        ohos:text_size="16fp"
        ohos:left_margin="20vp"
        ohos:top_margin="20vp" />

    <TextField
        ohos:id="$+id:input_username"
        ohos:width="match_parent"
        ohos:height="45vp"
        ohos:hint="请输入用户名"
        ohos:left_margin="20vp"
        ohos:top_margin="5vp" />
</DirectionalLayout>
DependentLayout 示例(XML)——登录界面
<DependentLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:width="match_parent"
    ohos:height="match_parent">

    <Text
        ohos:id="$+id:title"
        ohos:width="match_content"
        ohos:height="match_content"
        ohos:text="用户登录"
        ohos:text_size="28fp"
        ohos:top_margin="60vp"
        ohos:horizontal_center="true" />

    <TextField
        ohos:id="$+id:username"
        ohos:width="300vp"
        ohos:height="50vp"
        ohos:hint="请输入用户名"
        ohos:below="$id:title"
        ohos:top_margin="30vp"
        ohos:horizontal_center="true" />

    <TextField
        ohos:id="$+id:password"
        ohos:width="300vp"
        ohos:height="50vp"
        ohos:hint="请输入密码"
        ohos:input_type="PASSWORD"
        ohos:below="$id:username"
        ohos:top_margin="15vp"
        ohos:horizontal_center="true" />

    <Button
        ohos:id="$+id:login_btn"
        ohos:width="300vp"
        ohos:height="50vp"
        ohos:text="登录"
        ohos:background_element="$graphic:button_bg"
        ohos:below="$id:password"
        ohos:top_margin="20vp"
        ohos:horizontal_center="true" />
</DependentLayout>

DependentLayout 的常用定位属性:

属性 说明
above 在指定组件上方
below 在指定组件下方
left_of 在指定组件左侧
right_of 在指定组件右侧
aligned_left 与指定组件左对齐
aligned_right 与指定组件右对齐
aligned_top 与指定组件顶部对齐
aligned_bottom 与指定组件底部对齐
horizontal_center 水平居中(值为 true)
vertical_center 垂直居中(值为 true)

9.4 图形资源 (graphic)

组件的背景、形状等通过 resources/base/graphic/ 目录下的 XML 文件定义:

<!-- graphic/button_bg.xml -->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:shape="rectangle">
    <corners ohos:radius="25vp"/>
    <solid ohos:color="#007DFF"/>
</shape>

常用图形属性:

属性 说明
ohos:shape 形状:rectangle/oval/line/ring
ohos:radius 圆角半径
ohos:cornerRadius 各角分别设置圆角
solid 填充颜色
stroke 边框(宽度+颜色)
gradient 渐变色

代码速查卡

组件/操作 API 说明
查找组件 findComponentById(ResourceTable.Id_xxx) 返回 Component,需强转
设置文本 text.setText("内容") Text/Button 通用
设置颜色 text.setTextColor(Color.RED) 使用 Color 常量
点击事件 component.setClickedListener(listener) 所有组件可用
加载布局 setUIContent(ResourceTable.Layout_xxx) 必须在 onStart() 中调用
弹出提示 new ToastDialog(ctx).setText("msg").show() 短暂提示
设置背景 component.setBackgroundElement() 传入 graphic 资源

与 Android/iOS 对比

特性 HarmonyOS (Java UI) Android (View) iOS (UIKit)
布局文件 XML (ohos 命名空间) XML (android 命名空间) Storyboard / XIB / 代码
线性布局 DirectionalLayout LinearLayout UIStackView
相对布局 DependentLayout ConstraintLayout / RelativeLayout Auto Layout
帧布局 StackLayout FrameLayout 重叠视图
列表 ListContainer RecyclerView UITableView
图形资源 graphic/ XML drawable/ XML 不支持 XML 定义
ID 查找 ResourceTable.Id_xxx R.id.xxx outlet 连接

⚠️ 踩坑回忆录

刚开始用 Java UI 做布局时,我把 setUIContent() 写在了 onActive() 里,结果每次切回页面都会重新加载布局,导致状态丢失。setUIContent() 必须在 onStart() 中调用,这是 AbilitySlice 的生命周期决定的。另外,通过 ID 查找组件时要用 ResourceTable.Id_xxx 而不是直接写字符串,我一开始写了 findComponentById("text_helloworld"),报了 NullPointerException,改成 findComponentById(ResourceTable.Id_text_helloworld) 才解决。

还有一个坑:DependentLayout 中引用其他组件时,被引用的组件必须定义在前面(XML 中先出现),否则编译会报错找不到组件。这个顺序依赖是 DependentLayout 的一大特点。


必做实操任务

序号 任务 难度
1 使用 DirectionalLayout 实现一个简单的表单页面(姓名+电话+提交按钮) ★★☆
2 使用 DependentLayout 实现一个完整的登录界面 ★★☆
3 创建圆形按钮背景的 graphic 资源文件 ★☆☆
4 使用 ListContainer 实现一个简单的列表展示 ★★★
5 实现登录页面,输入验证并弹出 Toast 提示 ★★★

学习检查清单

  • 能说出 Java UI 框架的核心类(Component、ComponentContainer)
  • 能使用至少 5 种常用 UI 组件
  • 能使用 DirectionalLayout 实现垂直/水平排列
  • 能使用 DependentLayout 实现相对定位
  • 能创建和使用 graphic 资源定义组件背景
  • 理解 setUIContent() 必须在 onStart() 中调用的原因
  • 能写出完整的登录界面

进阶方向

  • 学习 TableLayout 和自定义布局
  • 深入学习 ListContainer 的 BaseItemProvider 适配器模式
  • 学习自定义组件和自定义绘制

Logo

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

更多推荐