第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 / 代码
线性布局DirectionalLayoutLinearLayoutUIStackView
相对布局DependentLayoutConstraintLayout / RelativeLayoutAuto Layout
帧布局StackLayoutFrameLayout重叠视图
列表ListContainerRecyclerViewUITableView
图形资源graphic/ XMLdrawable/ XML不支持 XML 定义
ID 查找ResourceTable.Id_xxxR.id.xxxoutlet 连接

⚠️ 踩坑回忆录

刚开始用 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、测试、元服务和应用上架分发等。

更多推荐