Android UI 转鸿蒙 ArkUI 开发范式对照文档

本文档面向有 Android 开发经验的工程师,帮助快速理解并迁移到 HarmonyOS ArkUI 声明式开发范式。


一、架构理念对照

维度 Android (XML/Compose) HarmonyOS (ArkUI)
UI 范式 XML 命令式 / Compose 声明式 ArkUI 声明式
编程语言 Java / Kotlin ArkTS (TypeScript 子集)
页面容器 Activity UIAbility
组件化 Fragment / @Composable @Component / @ComponentV2
状态管理 ViewModel + LiveData / remember + State @State/@Local + @Observed/@ObservedV2
导航 Intent / Navigation Compose Navigation + NavPathStack
资源引用 R.string.xxx / R.drawable.xxx $r(‘app.string.xxx’) / $r(‘app.media.xxx’)
构建 Gradle Hvigor
包管理 Maven / Gradle OHP

二、生命周期对照

2.1 页面生命周期

Android Activity                        HarmonyOS UIAbility
─────────────────                       ──────────────────
onCreate()                         →    onCreate()
onStart()                          →    onWindowStageCreate()
onResume()                         →    onForeground()
onPause()                          →    onBackground()
onStop()                           →    (无直接对应)
onDestroy()                        →    onDestroy()

2.2 组件生命周期

Android Fragment                        HarmonyOS @Component
─────────────────                       ──────────────────
onAttach()                         →    (无对应)
onCreateView()                      →    build()
onViewCreated()                     →    (在build中完成)
onStart() / onResume()              →    aboutToAppear()
onPause() / onStop()                →    aboutToDisappear()
onDestroyView()                      →    (无对应)
onDetach()                          →    (无对应)

注意:@Component 没有 onResume/onPause 概念。如需感知页面可见性,在页面的 onPageShow/onPageHide 中通过状态变量通知组件。


三、布局组件映射

3.1 XML 布局 → ArkUI 布局

Android XML HarmonyOS ArkUI 说明
LinearLayout(vertical) Column 垂直线性排列
LinearLayout(horizontal) Row 水平线性排列
RelativeLayout RelativeContainer 相对定位布局
FrameLayout Stack 层叠布局
ConstraintLayout RelativeContainer / Flex 复杂约束用 RelativeContainer,弹性用 Flex
ScrollView Scroll 可滚动容器
NestedScrollView Scroll + List 嵌套滚动
ViewPager / ViewPager2 Swiper 轮播/页面切换
TabLayout + ViewPager Tabs + TabContent 选项卡
RecyclerView List + LazyForEach / Repeat 高性能列表
GridView Grid + GridItem 网格布局
FlexboxLayout Flex 弹性布局
GridLayout GridRow + GridCol 栅格布局(响应式)
DrawerLayout Panel / 自定义 Stack 抽屉布局
CoordinatorLayout Column + 手势/动画 协调布局(需自行实现)

3.2 关键属性映射

通用属性
Android XML 属性 ArkUI 属性 示例
layout_width="match_parent" .width('100%').width('100%')
layout_height="wrap_content" .height('auto') 或不设置
layout_margin="16dp" .margin(16) 支持 vp/px 单位
layout_padding="16dp" .padding(16)
layout_gravity="center" .alignSelf(ItemAlign.Center) 父容器交叉轴对齐
gravity="center" .justifyContent(FlexAlign.Center) + .alignItems(HorizontalAlign.Center) 内容对齐
visibility="gone" .visibility(Visibility.None)
visibility="invisible" .visibility(Visibility.Hidden)
visibility="visible" .visibility(Visibility.Visible)
background="@color/xxx" .backgroundColor($r('app.color.xxx'))
elevation="4dp" .shadow({ radius: 4 })
alpha="0.5" .opacity(0.5)
clickable="true" .onClick(() => {})
enabled="false" .enabled(false)
LinearLayout → Column/Row
<!-- Android XML -->
<LinearLayout
    android:orientation="vertical"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView android:layout_weight="1" />
    <TextView android:layout_weight="2" />
</LinearLayout>
// ArkUI
Column() {
  Text('item1').layoutWeight(1)
  Text('item2').layoutWeight(2)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
XML 属性 ArkUI 属性
orientation="vertical" 使用 Column
orientation="horizontal" 使用 Row
layout_weight="1" .layoutWeight(1)
gravity="center_vertical" Column: .justifyContent(FlexAlign.Center)
gravity="center_horizontal" Column: .alignItems(HorizontalAlign.Center)
ConstraintLayout → RelativeContainer
RelativeContainer() {
  Text('Title')
    .id('title')
    .alignRules({ top: { anchor: '__container__', align: VerticalAlign.Top } })

  Text('Subtitle')
    .id('subtitle')
    .alignRules({
      top: { anchor: 'title', align: VerticalAlign.Bottom },
      left: { anchor: 'title', align: HorizontalAlign.Start }
    })
}

四、UI 组件映射

4.1 基础组件

Android (XML/Compose) HarmonyOS ArkUI 说明
TextView / Text() Text 文本显示
EditText / TextField() TextInput 单行输入
EditText(multiline) / TextField(maxLines) TextArea 多行输入
Button / Button() Button 按钮
ImageView / Image() Image 图片显示
ProgressBar(horizon) / LinearProgressIndicator Progress(Linear) 线性进度条
ProgressBar(circle) / CircularProgressIndicator Progress(Ring) / LoadingProgress 圆形进度
CheckBox / Checkbox() Checkbox 复选框
RadioButton / RadioButton() Radio + RadioContainer 单选按钮
Switch / Switch() Toggle(type: SwitchType) 开关
SeekBar / Slider() Slider 滑块
RatingBar / RatingBar() Rating 评分
Spinner / 下拉选择 Select 下拉选择
SearchView / SearchBar() Search 搜索框
WebView / WebView() Web 网页视图
VideoView / VideoPlayer() Video 视频播放

4.2 对话框与弹窗

Android HarmonyOS ArkUI 说明
AlertDialog.Builder AlertDialog / promptAction.showDialog 提示对话框
BottomSheetDialog bindSheet 半模态弹窗
DialogFragment CustomDialog / @CustomDialog 自定义弹窗
Toast.makeText promptAction.showToast 轻提示
PopupMenu bindMenu 菜单弹窗
DatePickerDialog DatePickerDialog 日期选择
TimePickerDialog TimePickerDialog 时间选择
Snackbar promptAction.showToast / 自定义 无直接对应

4.3 列表组件

Android HarmonyOS ArkUI 说明
ListView + Adapter List + ForEach 简单列表
RecyclerView + Adapter + ViewHolder List + LazyForEach 高性能列表
RecyclerView + GridLayoutManager Grid + LazyForEach 网格列表
RecyclerView + StaggeredGridLayoutManager WaterFlow + LazyForEach 瀑布流
ListAdapter BasicDataSource / IDataSource 数据源抽象
DiffUtil IDataSourcenotifyDataChange 数据变更通知
ItemDecoration List.divider() / 自定义 ListItem 间距 列表分割线
ItemAnimator animateItem / 属性动画 列表动画
RecyclerView → List + LazyForEach 对照
// Android Compose
LazyColumn {
    items(courseList, key = { it.id }) { course ->
        CourseCard(course = course)
    }
}
// ArkUI
List() {
  LazyForEach(this.dataSource, (item: CourseItem) => {
    ListItem() {
      CourseCard({ course: item })
    }
  }, (item: CourseItem) => item.id.toString())
}
.cachedCount(5)
.divider({ strokeWidth: 1, color: '#E0E0E0' })

关键差异

  • 无需 Adapter/ViewHolder,组件本身即 ViewHolder,框架自动复用
  • LazyForEach 第三个参数是 key 生成函数,必须返回唯一字符串
  • cachedCount 替代 RecyclerView 的缓存策略

五、Compose → ArkUI 范式对照

5.1 核心概念映射

Jetpack Compose ArkUI 说明
@Composable @Component / @ComponentV2 组件声明
remember @Local (V2) / @State (V1) 组件内部状态
mutableStateOf @Local (V2) / @State (V1) 可变状态
State<T> @Local (V2) / @State (V1) 状态包装
Modifier 链式属性方法 样式修饰
LaunchedEffect aboutToAppear + 异步任务 副作用
DisposableEffect aboutToAppear + aboutToDisappear 生命周期副作用
SideEffect 直接在事件回调中处理 同步副作用
rememberCoroutineScope 直接使用 async/await 协程
CompositionLocal @Provider / @Consumer (V2) 作用域传递
NavHost / NavGraph Navigation + NavPathStack 导航图

5.2 状态管理对照

Jetpack Compose ArkUI V2 (推荐) ArkUI V1
var text by remember { mutableStateOf("") } @Local text: string = '' @State text: string = ''
传参 (text: String) @Param text: string = '' @Prop text: string = ''
回调 (onChange: (String) -> Unit) @Event onChange: (s: string) => void 回调函数属性
ViewModel + StateFlow @ObservedV2 + @Trace @Observed + @ObjectLink
MutableLiveData @Trace 属性 @Watch 监听

5.3 Modifier → 链式属性

// Compose
Text(
    text = "Hello",
    modifier = Modifier
        .fillMaxWidth()
        .padding(16.dp)
        .background(Color.Blue)
        .clickable { /* ... */ },
    color = Color.White,
    fontSize = 16.sp
)
// ArkUI
Text('Hello')
  .width('100%')
  .padding(16)
  .backgroundColor(Color.Blue)
  .onClick(() => { /* ... */ })
  .fontColor(Color.White)
  .fontSize(16)

区别:Compose 用 Modifier 参数集中传递样式;ArkUI 用链式方法调用。功能等价,表达方式不同。

5.4 常见组件对照

Compose ArkUI
Column { } Column() { }
Row { } Row() { }
Box { } Stack() { }
LazyColumn { } List() { LazyForEach(...) }
LazyRow { } List({ listDirection: Axis.Horizontal }) { }
Grid { } Grid() { }
Scaffold { } 无直接对应,用 Column + 自定义 TitleBar + Tabs 组合
TopAppBar Navigationtitle 属性 / 自定义 TitleBar
BottomNavigation Tabs 的底部栏模式
FloatingActionButton 自定义 Button + Stack 定位
Card { } Column + .borderRadius() + .shadow()
Chip / FilterChip 自定义组件 / Toggle
Divider() Divider()
Spacer(modifier = Modifier.height(8.dp)) Blank().height(8)
Surface { } Column().borderRadius().backgroundColor()

六、导航路由对照

6.1 页面跳转

// Android: Intent
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("courseId", courseId)
startActivity(intent)
// ArkUI: router (简单场景)
import { router } from '@kit.ArkUI'

router.pushUrl({
  url: 'pages/DetailPage',
  params: { courseId: this.courseId }
})
// ArkUI: Navigation + NavPathStack (推荐)
this.navPathStack.pushPath({ name: 'DetailPage', param: { courseId: this.courseId } })

6.2 导航对照表

Android HarmonyOS ArkUI
startActivity() router.pushUrl() / navPathStack.pushPath()
finish() router.back() / navPathStack.pop()
startActivityForResult() navPathStack.pushPath() + 回调
Intent.putExtra() params: { key: value }
getIntent().getExtra() router.getParams()['key']
Navigation Compose NavHost Navigation { NavPathStack }
NavGraph navDestination 路由表
BottomNavigationView Tabs 组件

七、资源管理对照

Android HarmonyOS ArkUI 说明
R.string.app_name $r('app.string.app_name') 字符串
R.drawable.icon $r('app.media.icon') 图片
R.color.primary $r('app.color.primary') 颜色
R.dimen.spacing $r('app.float.spacing') 尺寸
R.raw.video $rawfile('video.mp4') 原始文件
getString(R.string.xxx) getContext().resourceManager.getStringSync($r('app.string.xxx')) 代码中获取
dp 单位 vp 单位 (1:1) 密度无关像素
sp 单位 fp 单位 字体缩放像素

资源目录结构

Android                          HarmonyOS
─────────                        ─────────
res/                             resources/
  values/                          base/
    strings.xml                      element/
    colors.xml                         string.json
    dimens.xml                         color.json
  drawable/                            float.json
  mipmap-hdpi/                       media/
  raw/                                 icon.png
                                    rawfile/
                                      video.mp4

八、数据存储对照

Android HarmonyOS 说明
SharedPreferences @ohos.data.preferences 轻量 KV 存储
Room / SQLite @ohos.data.relationalStore 关系型数据库
DataStore @ohos.data.preferences 偏好存储
File (内部存储) @ohos.file.fs 文件操作
ContentProvider DataShareExtension 数据共享
GreenDAO @ohos.data.relationalStore ORM 需自行封装

SharedPreferences 迁移示例

// Android
val sp = getSharedPreferences("config", MODE_PRIVATE)
sp.edit().putString("token", token).apply()
val token = sp.getString("token", "")
// ArkUI
import { preferences } from '@kit.ArkData'

let prefs = await preferences.getPreferences(getContext(this), 'config')
await prefs.put('token', token)
await prefs.flush()
let token = await prefs.get('token', '')

注意:鸿蒙 preferences 全部是异步操作,必须用 awaitflush() 必须显式调用才会持久化。


九、事件交互对照

Android (XML/Compose) HarmonyOS ArkUI
setOnClickListener / .clickable { } .onClick(() => {})
setOnLongClickListener / .longClickable { } .onLongPress(() => {}) / 手势绑定
setOnTouchListener .onTouch((e) => {})
setOnKeyListener .onKeyEvent((e) => {})
addTextChangedListener .onChange((value) => {})
setOnFocusChangeListener .onFocus(() => {}) / .onBlur(() => {})
SwipeRefreshLayout Refresh 组件
onTouch 手势识别 GestureGroup / PanGesture / TapGesture
onScrollListener .onScrollFrameBegin() / .onScroll()
ItemTouchHelper (拖拽/滑动) List.onDragStart() / .onSwipe()

手势体系对照

// Compose
Modifier.pointerInput(Unit) {
    detectTapGestures(onLongPress = { /* ... */ })
    detectDragGestures { change, dragAmount -> /* ... */ }
}
// ArkUI
.gesture(
  GestureGroup(GestureMode.Exclusive,
    LongPressGesture().onAction(() => { /* ... */ }),
    PanGesture().onActionUpdate((e: GestureEvent) => { /* ... */ })
  )
)

十、动画对照

Android (XML/Compose) HarmonyOS ArkUI
ObjectAnimator animateTo() 显式动画
ValueAnimator animateTo() + 闭包
Transition / AnimatedVisibility transition() 转场动画
animateFloatAsState animateTo() / animationDuration
Animatable @AnimatableExtend 自定义动画属性
Lottie @ohos.multimedia.media / 自定义 Canvas 动画
SharedElement geometryTransition() 共享元素转场
MotionLayout 无直接对应,组合属性动画实现
// ArkUI 显式动画
animateTo({ duration: 300, curve: Curve.EaseInOut }, () => {
  this.width = 200
  this.opacity = 1.0
})

// ArkUI 属性动画
Text('Hello')
  .width(this.width)
  .animation({ duration: 300, curve: Curve.EaseInOut })

十一、MVVM 架构对照

11.1 架构映射

Android MVVM HarmonyOS MVVM
ViewModel @ObservedV2 class (ViewModel)
MutableLiveData<T> @Trace 属性
LiveData.observe() @Watch / 自动 UI 刷新
Repository Service / Repository (同概念)
DataBinding 自动状态驱动 UI (无需绑定)

11.2 目录结构

Android                          HarmonyOS
─────────                        ─────────
app/                             entry/src/main/ets/
  model/                           model/
    User.kt                          User.ets
  viewmodel/                       viewmodel/
    UserViewModel.kt                 UserViewModel.ets
  view/                            view/
    Activity/                        pages/
    Fragment/                        components/
    Adapter/                         (无 Adapter)
  repository/                      service/
    UserRepository.kt                UserRepository.ets

11.3 代码对照

// Android ViewModel
class UserViewModel : ViewModel() {
    private val _userName = MutableLiveData("")
    val userName: LiveData<String> = _userName

    fun loadUser() {
        viewModelScope.launch {
            _userName.value = repository.getUserName()
        }
    }
}
// ArkUI ViewModel (V2)
@ObservedV2
class UserViewModel {
  @Trace userName: string = ''

  async loadUser() {
    this.userName = await repository.getUserName()
  }
}

@Entry
@ComponentV2
struct UserPage {
  @Local viewModel: UserViewModel = new UserViewModel()

  aboutToAppear() {
    this.viewModel.loadUser()
  }

  build() {
    Column() {
      Text(this.viewModel.userName)
    }
  }
}

十二、常见踩坑与注意事项

12.1 ArkTS 语法限制

限制项 说明 迁移策略
禁止 any 类型 ArkTS 不允许 any/unknown 定义具体接口/类
禁止结构化类型 不支持鸭子类型,只支持名义类型 使用 extends / implements
禁止 as 类型断言 不允许强制类型转换 使用类型守卫或正确声明类型
禁止动态属性访问 obj[key] 不允许 使用 Map 或 Record
对象字面量需类型上下文 { name: 'test' } 必须有类型 指定变量类型或函数参数类型
禁止 for...in 不允许 for…in 遍历 使用 Object.keys() + for...of

12.2 状态管理常见问题

问题 原因 解决
修改对象属性 UI 不刷新 @State 对对象是浅比较 使用 @ObservedV2 + @Trace,或重新赋值整个对象
数组元素修改不刷新 直接 arr[i] = newVal 不触发 使用 arr.splice(i, 1, newVal)arr = [...arr]
子组件状态丢失 页面重新渲染时子组件被重建 使用 @Reusable 装饰器标记可复用组件
LazyForEach 更新异常 key 生成函数返回重复值 确保第三个参数返回唯一稳定的字符串

12.3 性能优化对照

Android 优化 HarmonyOS 优化
RecyclerView.setHasFixedSize(true) List 设置固定宽高
RecyclerView.setRecycledViewPool() cachedCount 设置预加载
ViewHolder 复用 @Reusable 组件复用
Glide 图片缓存 Image 组件内置三级缓存
避免嵌套层级过深 同理,扁平化布局
DiffUtil 精确更新 LazyForEach + IDataSource 的 notifyDataChange
setOnClickListener(null) .hitTestBehavior(HitTestMode.None)
ViewStub 延迟加载 if 条件渲染

十三、快速迁移检查清单

页面迁移

  • Activity → UIAbility,调整生命周期
  • XML 布局 → ArkUI 声明式组件树
  • Fragment → @Component 自定义组件
  • ViewPager → Swiper
  • TabLayout → Tabs + TabContent
  • RecyclerView → List + LazyForEach
  • ScrollView → Scroll

状态迁移

  • ViewModel → @ObservedV2 class
  • LiveData → @Trace 属性
  • remember/mutableStateOf → @Local (V2) / @State (V1)
  • Compose 参数传递 → @Param (V2) / @Prop (V1)
  • 回调 → @Event (V2)

导航迁移

  • Intent → Want / NavPathStack
  • startActivity → router.pushUrl / navPathStack.pushPath
  • Navigation Compose → Navigation + NavPathStack

资源迁移

  • R.string → $r(‘app.string.xxx’)
  • R.drawable → $r(‘app.media.xxx’)
  • R.color → $r(‘app.color.xxx’)
  • dp → vp
  • sp → fp

数据迁移

  • SharedPreferences → @ohos.data.preferences
  • Room/SQLite → @ohos.data.relationalStore
  • File → @ohos.file.fs
Logo

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

更多推荐