第9章_HarmonyOs图解 用Java开发UI

第9章 HarmonyOs图解 Java UI 开发

HarmonyOS 学习系统 | 阶段二:进阶实战期

建议学习时长:2-3 周


学习目标

序号 能力
1 理解 Java UI 框架的组件树结构和命令式编程模型
2 掌握常用 UI 组件(Text、Button、Image、TextField 等)的使用
3 熟练使用四种布局(Directional、Dependent、Stack、Table)
4 能独立实现完整的 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 查找组件:

java 复制代码
Text text = (Text) findComponentById(ResourceTable.Id_text_helloworld);
text.setText("新的文本内容");

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

按钮点击事件
java 复制代码
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)
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)------登录界面
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 文件定义:

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 适配器模式
  • 学习自定义组件和自定义绘制

相关推荐
哦虎!5 小时前
【JavaEE】网络初识
java
for_ever_love__5 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
程序猿追6 小时前
kotlin-retry 接入鸿蒙后,怎样确认它真的会停止重试
开发语言·kotlin·harmonyos
我是人✓6 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
欣栀♡6 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm
IT研究室7 小时前
最新计算机毕业设计选题推荐-基于spring boot的葡萄酒文化宣传网站-网站-文档指导-Java-springboot
java·spring boot·课程设计
慧都小项7 小时前
MyEclipse 中创建和测试 JAX-RS REST 接口:从项目配置到 REST Explorer
java·restful·myeclipse·jax-rs
Wang's Blog7 小时前
Java 项目实战: 交友项目 - 入门案例:编写 Dubbo 服务提供者
java·dubbo·交友
秋饼7 小时前
Spring AI 2.0 结构化输出企业级实战:从 BeanOutputConverter 源码到生产级解析容错
java·ai·技术分享·后端开发
摇滚侠7 小时前
《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 9 章 机器码与汇编语言 阅读笔记 9
java·开发语言·笔记