在Tabs中加载外部组件记得先引用文件,项目的基础结构代码如下:

import home from ‘./Home/Home’;
 import contacts from ‘./Contact/Contacts’;
 import Discover from ‘./Discover/Discover’;
 import My from ‘./My/My’;@Entry
 @Component
 struct Index {
 build() {
 Column() {
 Tabs({ barPosition: BarPosition.End, controller: this.controller }) {
 //首页
 TabContent() {
 home()
 }.tabBar()
 //通讯录
 TabContent() {
 contacts()
 }.tabBar()
 //发现
 TabContent() {
 Discover()
 }.tabBar()
 //我
 TabContent() {
 My()
 }.tabBar()
 }
 .vertical(false)
 .barHeight(56)
 .onChange((index: number) => {
 this.currentIndex = index
 })
 .width(‘100%’)
 .height(‘100%’)
 .backgroundColor(‘#F1F3F5’)
 }
 .width(‘100%’)
 .height(‘100%’)
 }


接下来就可以分别在子控制器中开发对应的模块了。

首页

python打包 鸿蒙笔记本运行_harmonyos

首先要注意的是微信、通讯录、发现、我这4个字控制器都是带导航栏的,所以最外部的容器是Navigation(),然后按照效果图配置导航栏的样式,比如首页的导航栏相关代码如下:

build() {
Navigation(){
}
 .title(this.NavigationTitle())
 .mode(NavigationMode.Stack)
 .titleMode(NavigationTitleMode.Mini)
 .hideBackButton(true)
 .menus(this.NavigationMenus())
 .size({ width: ‘100%’, height: ‘100%’ })
 .backgroundColor(‘rgb(237,237,237)’)
 }
 @Builder NavigationMenus() {
 Row() {
 Image(‘/images/we_add.png’)
 .size({ width: 24, height: 24 })
 .margin({ left: 5 })
 .onClick(()=>{
 animateTo({
 duration: 200,
 }, () => {
 if(this.menuOpacity == 0){
 this.menuOpacity = 1
 }else if(this.menuOpacity == 1){
 this.menuOpacity = 0
 }})
 })
 }.justifyContent(FlexAlign.End)
 }@Builder NavigationTitle() {
 Row(){
 Text(“微信”)
 .width(‘100’)
 }
 .width(‘100%’)
 .justifyContent(FlexAlign.Center)
 }

然后首页里比较难就是右上角弹窗了,虽然系统提供了弹窗组件menu,但是样式相差比较大,所以我们需要自己写一个。

弹窗可以分为两个部分,尖尖和矩形列表,它俩是一个Column布局:

python打包 鸿蒙笔记本运行_华为_02

这样代码就不难写了,首先绘制一个三角形,再放一个List组件就行了,具体代码如下:

Flex({direction:FlexDirection.Column,justifyContent:FlexAlign.Center}){
 //绘制三角形
 Path()
 .width(20)
 .height(20)
 .commands(‘M25 0 L50 50 L0 50 Z’)
 .fill(‘rgb(76,76,76)’)
 .stroke(‘rgb(76,76,76)’)
 .padding(0)
 .margin(0)
 .position({x:95,y:0})//矩形列表
 List(){
 ListItem(){
 MenuRow({imagePath:‘/images/menu_group.png’,titleString:‘发起群聊’})
 }
 ListItem(){
 MenuRow({imagePath:‘/images/menu_add.png’,titleString:‘添加朋友’})
 }
 ListItem(){
 MenuRow({imagePath:‘/images/menu_scan.png’,titleString:‘扫一扫’})
 }
 ListItem(){
 MenuRow({imagePath:‘/images/menu_purchase.png’,titleString:‘收付款’})
 }
 }
 .margin(0)
 .borderRadius(5).padding({left:12})
 .divider({ strokeWidth: 1, color: ‘rgb(130,130,130)’, startMargin: 20, endMargin: 0 }) // 每行之间的分界线
 .backgroundColor(‘rgb(76,76,76)’)
 .width(130)
 .height(180)}
 .opacity(this.menuOpacity)
 .width(130)
 .height(200)
 .margin({right:10,top:-10})

弹窗开发好了,新的问题来了,怎么样把它放到右上角呢?如果你看过层叠布局Stack的对齐样式,这个问题就不难了,在对齐样式中有一个TopEnd,然后微调一下边距就完成了。

python打包 鸿蒙笔记本运行_ci_03

通讯录

这个页面需要讲一下的地方是list组件的分块和右侧字母索引。

可以看到这个节目同一个List列表中出现了不同的样式,即不同的

ListItemGroup,上图中每一个红框为一个ListItemGroup,第一个ListItemGroup比较简单,但是下面3个是包含了itemHead的,代码示例如下:

@Builder itemHead(text:string) {
 Text(text)
 .fontSize(14)
 .backgroundColor(Color.White)
 .width(“100%”)
 .padding(3)
 }ListItemGroup({header:this.itemHead(item[‘letter’])}){
 ListItem(){
 Flex({direction:FlexDirection.Row,alignItems:ItemAlign.Center}){
 Image(p[‘avtar’])
 .width(45)
 .height(45)
 .borderRadius(5)
 Text(p[‘name’])
 .fontSize(18)
 .margin({left:10})
 }
 .height(55)
 }
 })}
 .margin({top:10})字母索引的话用语言不太好讲,直接看代码来的更快:
@State letters: string[] = [‘L’,‘W’,‘Z’]
AlphabetIndexer({ arrayValue: this.letters, selected: 0 })
 .color(Color.Black)
 .selectedColor(0xFFFFFF) // 选中项文本颜色
 .popupColor(0xFFFAF0) // 弹出框文本颜色
 .selectedBackgroundColor(‘rgb(1,196,194)’) // 选中项背景颜色
 .popupBackground(0xD2B48C) // 弹出框背景颜色
 .usingPopup(true) // 是否显示弹出框
 .selectedFont({ size: 13, weight: FontWeight.Bolder }) // 选中项字体样式
 .popupFont({ size: 30, weight: FontWeight.Bolder }) // 弹出框内容的字体样式
 .itemSize(20) // 每一项的尺寸大小
 .alignStyle(IndexerAlign.Left) // 弹出框在索引条左侧弹出
 .onSelect((index: number) => {
 console.info(this.letters[index] + ’ Selected!')
 })
 .onPopupSelect((index: number) => {
 console.info(‘onPopupSelected:’ + index)
 })

至于发现和我这两个模块都比较简单,不再一一赘述。