本文分别使用 Jetpack Compose(Android)、ArkTS(纯血鸿蒙)实现带顶部导航栏、可滚动垂直线性列表的基础页面,先拆解页面通用构成模块做简要说明,最后附上两端完整可运行代码。
一、Android Compose 页面模块拆解整体页面分为 4 个核心模块,各司其职:
- Activity 承载容器继承 AppCompatActivity,在 onCreate 中调用 setContent 挂载 Compose 根布局,同时提供页面关闭回调方法,作为返回按钮的执行逻辑。
- 顶部导航栏 TopAppBar使用 Material3 CenterAlignedTopAppBar 居中标题导航栏,包含左侧返回图标按钮、中间页面标题;可自定义导航栏背景、文字主题色,点击返回按钮执行页面关闭。
- Scaffold 页面脚手架Compose 标准页面容器,统一管理顶部栏与内容区域边距 paddingValues,自动处理导航栏遮挡内容问题。
- 可滚动垂直线性内容区外层:verticalScroll 开启纵向滚动,Column 作为垂直线性布局,设置上下、左右对齐规则;子项:抽取独立 @Composable 组件 PagerItem,循环渲染 3 条文本条目,统一设置条目上下内边距。
分模块片段示例1、Activity 入口容器片段class FirstComposeAct: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MaterialTheme { MainPage(onBackClick = { finish() }) } } }}2、顶部导航栏片段CenterAlignedTopAppBar( title = { Text("列表页面", fontSize = 18.sp, fontWeight = FontWeight.Bold) }, navigationIcon = { IconButton(onClick = onBackClick) { Icon(Icons.Filled.ArrowBack, contentDescription = "返回") } }, colors = TopAppBarDefaults.centerAlignedTopAppBarColors(containerColor = Color.White))3、滚动线性列表与子项片段val state = rememberScrollState()Column( modifier = Modifier.fillMaxSize().verticalScroll(state).padding(paddingValues), verticalArrangement = Arrangement.Top, horizontalAlignment = Alignment.Start) { repeat(3) { index -> PagerItem( modifier = Modifier.fillMaxWidth().padding(vertical = 20.dp), page = index ) }}
@Composablefun PagerItem(modifier: Modifier, page: Int) { Text("第 ${page + 1} 页", modifier = modifier, fontSize = 24.sp, fontWeight = FontWeight.Bold)}
完整可运行代码import androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport androidx.compose.foundation.layout.Arrangementimport androidx.compose.foundation.layout.Columnimport androidx.compose.foundation.layout.fillMaxSizeimport androidx.compose.foundation.layout.fillMaxWidthimport androidx.compose.foundation.layout.paddingimport androidx.compose.foundation.verticalScrollimport androidx.compose.material.icons.Iconsimport androidx.compose.material.icons.filled.ArrowBackimport androidx.compose.material3.ExperimentalMaterial3Apiimport androidx.compose.material3.Iconimport androidx.compose.material3.IconButtonimport androidx.compose.material3.MaterialThemeimport androidx.compose.material3.Scaffoldimport androidx.compose.material3.Textimport androidx.compose.material3.TopAppBarDefaultsimport androidx.compose.runtime.Composableimport androidx.compose.runtime.rememberScrollStateimport androidx.compose.ui.Alignmentimport androidx.compose.ui.Modifierimport androidx.compose.ui.graphics.Colorimport androidx.compose.ui.text.font.FontWeightimport androidx.compose.ui.unit.sp
class FirstComposeAct: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MaterialTheme { MainPage(onBackClick = { finish() }) } } }
fun back(){ finish() }
@OptIn(ExperimentalMaterial3Api::class) @Composable fun MainPage(onBackClick: () -> Unit) { Scaffold( topBar = { CenterAlignedTopAppBar( title = { Text( text = "列表页面", fontSize = 18.sp, fontWeight = FontWeight.Bold ) }, navigationIcon = { IconButton(onClick = onBackClick) { Icon( imageVector = Icons.Filled.ArrowBack, contentDescription = "返回", tint = MaterialTheme.colorScheme.onSurface ) } }, colors = TopAppBarDefaults.centerAlignedTopAppBarColors( containerColor = Color.White, titleContentColor = MaterialTheme.colorScheme.onSurface ) ) } ) { paddingValues -> val state = rememberScrollState() Column( modifier = Modifier .fillMaxSize() .verticalScroll(state) .padding(paddingValues), verticalArrangement = Arrangement.Top, horizontalAlignment = Alignment.Start ) { repeat(3) { index -> PagerItem( modifier = Modifier .fillMaxWidth() .padding(vertical = 20.dp), page = index ) } } } }
@Composable fun PagerItem(modifier: Modifier, page: Int) { Text("第 ${page + 1} 页", modifier = modifier, fontSize = 24.sp, fontWeight = FontWeight.Bold) }}
二、鸿蒙 ArkTS 页面模块拆解页面同样拆分为 4 个对应模块,逻辑与 Android 端一一对应:
- 页面入口组件 @Entry @Component页面根组件,定义页面标题状态变量,提供页面生命周期回调 aboutToAppear / aboutToDisappear,build 方法为页面渲染入口。
- 自定义顶部导航栏 @Builder封装 NavTopBar 自定义构建器,使用 Row 水平布局承载返回图标、页面标题;调用系统返回路由 router.back() 实现页面回退,适配系统主题色。
- 页面根垂直容器 Column顶层 Column 占满全屏,分为导航栏、滚动内容两大区域,通过 layoutWeight(1) 让滚动区域自动填充剩余屏幕高度。
- Scroll 可滚动垂直线性列表外层:Scroll 开启纵向滚动,内部嵌套 Column 实现垂直线性布局;子项:抽取 PageItem 独立 Builder 组件,使用 ForEach 循环渲染 3 条文本条目,统一设置上下外边距。
分模块片段示例1、页面根组件入口片段@Entry@Componentstruct MyPage { pageTitle: ResourceStr = "列表页面" aboutToAppear(): void {} aboutToDisappear(): void {} build() { Column() { this.NavTopBar(this.pageTitle) // 滚动列表区域 }.width("100%").height("100%") }}
2、自定义顶部导航栏 Builder 片段@BuilderNavTopBar(title: ResourceStr) { Row() { Image($r("sys.media.ohos_ic_back")) .width(24).height(24) .onClick(() => { router.back() }) Text(title).fontSize(18).fontWeight(FontWeight.Bold) } .width("100%") .justifyContent(FlexAlign.Start) .alignItems(VerticalAlign.Center)}
3、滚动线性列表与子项片段Scroll() { Column() { ForEach([0, 1, 2], (item: number) => { this.PageItem(item) }) }.width("100%")}.layoutWeight(1).scrollBar(BarState.Auto)
@BuilderPageItem(index: number) { Text(第 ${index + 1} 页) .width("100%") .fontSize(24) .margin({ top: 20, bottom: 20 })}
完整代码import { router } from '@kit.ArkUI'
@Entry@Componentstruct MyPage { pageTitle: ResourceStr = "列表页面"
aboutToAppear(): void { }
aboutToDisappear(): void { }
@Builder NavTopBar(title: ResourceStr) { Row() { Image($r("sys.media.ohos_ic_back")) .width(24) .height(24) .margin({ right: 12 }) .onClick(() => { router.back() })
Text(title) .fontSize(18) .fontWeight(FontWeight.Bold) .fontColor($r("sys.color.ohos_id_color_text_primary")) } .width("100%") .padding({ left: 16, right: 16, top: 10, bottom: 10 }) .justifyContent(FlexAlign.Start) .alignItems(VerticalAlign.Center) .backgroundColor($r("sys.color.ohos_id_color_background")) }
@Builder PageItem(index: number) { Text(第 ${index + 1} 页) .width("100%") .fontSize(24) .fontWeight(FontWeight.Bold) .margin({ top: 20, bottom: 20 }) .fontColor($r("sys.color.ohos_id_color_text_primary")) }
build() { Column() { this.NavTopBar(this.pageTitle)
Scroll() { Column() { ForEach([0, 1, 2], (item: number) => { this.PageItem(item) }) } .width("100%") .padding({ left: 16, right: 16 }) } .layoutWeight(1) .scrollBar(BarState.Auto) } .width("100%") .height("100%") .backgroundColor($r("sys.color.ohos_fa_background")) }}