华为鸿蒙开发笔记

记在前面

官方文档链接

因无法直接使用chatgpt进行编程(悲,2024/10),故记录笔记,方便查阅,基于arkts语言

DevEco

中文

deveco是默认有中文包的,所以在市场里面搜不错,而应该在已安装里面搜索,然后启用就行了

测试

对ts进行单独测试

打开entry/src/test/LocalUnit.test.ets

将需要测试的代码附加再后面,然后就可以运行了,如下面测试代码

ts 复制代码
const first: string = "Hello World";
console.log(first);

常用组件

大小单位

如下,有两种设置方式

ts 复制代码
@Entry
@Component
struct Index {
  build() {
    Column({ }) {
      Text()
        .width(360)
        .height(360)
        .backgroundColor(0x0000FF)
      Text()
        .width('100%')
        .height('50%')
        .backgroundColor(0x00FF00)
    }
  }
}

Text

ts 复制代码
Text('HarmonyOS')
  .fontColor(Color.Blue)
  .fontSize(40)
  .fontStyle(FontStyle.Italic)
  .fontWeight(FontWeight.Bold)
  .textAlign(TextAlign.Center)

使用资源文件

ts 复制代码
Text($r('app.string.EntryAbility_label'))

Image

资源图片

ts 复制代码
Image($r("app.media.image2"))
  .objectFit(ImageFit.Cover)
  .backgroundColor(0xCCCCCC)
  .width(100)
  .height(100)
  • Contain:保持宽高比进行缩小或者放大,使得图片完全显示在显示边界内。

  • Cover(默认值):保持宽高比进行缩小或者放大,使得图片两边都大于或等于显示边界。

  • Auto:自适应显示。

  • Fill:不保持宽高比进行放大缩小,使得图片充满显示边界。

  • ScaleDown:保持宽高比显示,图片缩小或者保持不变。

  • None:保持原有尺寸显示。

网络图片

Image('https://www.example.com/xxx.png')

为了成功加载网络图片,您需要在module.json5文件中申明网络访问权限。

json 复制代码
{
    "module" : {
        "requestPermissions":[
           {
             "name": "ohos.permission.INTERNET"
           }
        ]
    }
}

TextInput

ts 复制代码
@Entry
@Component
struct Test {
  @State text: string = ''

  build() {
    Column() {
      TextInput({ placeholder: '请输入账号' })
        .caretColor(Color.Blue)
        .onChange((value: string) => {
          this.text = value
        })
      Text(this.text)
    }
  }
}

Button

点击事件

ts 复制代码
@Entry
@Component
struct Test {
  @State num: number = 0

  build() {
    Column() {
      Button('click me', { type: ButtonType.Capsule, stateEffect: true })
      .onClick(() => {
        this.num+=1
        })
      Text(this.num.toString())
    }
  }
}

type用于定义按钮样式三种Capsule,Normal,Circle

stateEffect用于设置按钮按下时是否开启切换效果,当状态置为false时,点击效果关闭,默认值为true。

图标按钮

ts 复制代码
@Entry
@Component
struct Test {

  build() {
    Column() {
      Button({ type: ButtonType.Circle, stateEffect: true }) {
        // Image($r('app.media.startIcon'))
        //   .width(30)
        //   .height(30)

        SymbolGlyph($r('sys.symbol.ohos_folder_badge_plus'))
          .fontSize(45)
      }
      .width(55)
      .height(55)
      .backgroundColor(0x00FF00)
    }
  }
}

LoadingProgress

ts 复制代码
LoadingProgress()
    .color(Color.Blue)
    .height(60)
    .width(60)

Foreach

接口如下

ts 复制代码
ForEach(
  arr: Array,
  itemGenerator: (item: any, index: number) => void,
  keyGenerator?: (item: any, index: number) => string
)

简单应用如下,

ts 复制代码
@Entry
@Component
struct Index {
  @State simpleList: Array<string> = ['one', 'two', 'three'];

  build() {
    Column() {
      ForEach(this.simpleList, (item: string,index:number) => {
        Text(`${index} : `+item)
          .fontSize(50)
      }, (item: string) => item)
    }
  }
}

List

如下,需要先用List,再使用ListItem指定显示项

ts 复制代码
@Entry
@Component
struct Index {
  @State results:number[] = [1,2,3,4,5,6]

  build() {
    List() {
      ForEach(this.results,(item:number)=>{
        ListItem(){
          Text(item.toString())
            .fontSize(30)
            .width('100%')
            .height('30%')
            .borderWidth(1)
            .borderColor(0x000000)
        }
      })
    }
  }
}

弹窗

简单提醒

基于模态窗口

ts 复制代码
Button('删除')
    .onClick(() => {
    if (this.selectedCardList.length == 0) {
        AlertDialog.show(
            {
                message: '已经删完了喔',
                autoCancel: true,
                alignment: DialogAlignment.Bottom,
            })
    } 

简单提醒2

ts 复制代码
onBackPress()
  {
    if (this.isShowToast()) {
      prompt.showToast(
        {
          message: $r('app.string.prompt_text'),
          duration: 1000
        });
      this.clickBackTimeRecord = new Date().getTime();
      return true;
    }
    return false;
  }

样式复用

使用@Style装饰,但只能在本文件中复用,说实话有点鸡肋

组件封装

ts 复制代码
class Article {
  id: string;
  title: string;
  brief: string;

  constructor(id: string, title: string, brief: string) {
    this.id = id;
    this.title = title;
    this.brief = brief;
  }
}

@Entry
@Component
struct ArticleListView {
  @State isListReachEnd: boolean = false;
  @State articleList: Array<Article> = []

  aboutToAppear(): void {
    for (let i = 1; i <= 4; i++) {
      const id = i.toString().padStart(3, '0'); // 格式化ID,如 '001', '002', etc.
      const title = `第${i}篇文章`;
      const content = '文章简介内容';
      this.articleList.push(new Article(id, title, content));
    }
  }

  loadMoreArticles() {
    this.articleList.push(new Article('007', '加载的新文章', '文章简介内容'));
  }

  build() {
    Column({ space: 5 }) {
      List() {
        ForEach(this.articleList, (item: Article) => {
          ListItem() {
            ArticleCard({ article: item })
              .margin({ top: 20 })
          }
        }, (item: Article) => item.id)
      }
      .padding(20)
      .scrollBar(BarState.Off)
    }
    .width('100%')
    .height('100%')
    .backgroundColor(0xF1F3F5)
  }
}

@Component
struct ArticleCard {
  @Prop article: Article;

  build() {
    Row() {
      Image($r('app.media.startIcon'))
        .width(80)
        .height(80)
        .margin({ right: 20 })

      Column() {
        Text(this.article.title)
          .fontSize(20)
          .margin({ bottom: 8 })
        Text(this.article.brief)
          .fontSize(16)
          .fontColor(Color.Gray)
          .margin({ bottom: 8 })
      }
      .alignItems(HorizontalAlign.Start)
      .width('80%')
      .height('100%')
    }
    .padding(20)
    .borderRadius(12)
    .backgroundColor('#FFECECEC')
    .height(120)
    .width('100%')
    .justifyContent(FlexAlign.SpaceBetween)
  }
}

布局

动画

导航及传参

页面跳转,以及使用provide和consume进行传参

Main Page

ts 复制代码
import { DetailPage } from './DetailPage';

@Entry
@Component
struct MainPage {
  @Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack()
  @Provide param: string ='param';


  build() {
    Column() {
      Navigation(this.pageInfos) {
          Button('Next Page')
            .align(Alignment.Center)
            .margin({ top: 100 })
            .borderRadius(12)
            .onClick(() => {
              this.pageInfos.pushPathByName("DetailPage",'')
            });
      }
      .title("Main Page")
      .navDestination(this.PageMap);
    }
  }

  @Builder
  PageMap(name: string) {
    if (name === "DetailPage") {
      DetailPage(); // 调用详情页面
    }
  }
}

Detail Page

ts 复制代码
@Component
export struct DetailPage {
  @Consume('pageInfos') pageInfos: NavPathStack;
  @Consume  param: string;

  build() {
    NavDestination() {
      Column() {
        Text(this.param)
          .fontSize(30)
          .margin({ top: 20 });
      }
    }
    .title("Detail Page")
    .onBackPressed(() => {
      this.pageInfos.pop();
      return true;
    });
  }
}

生命周期事件

页面生命周期

被@Entry装饰的组件生命周期

onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景

onPageHide:页面每次隐藏时触发一次,包括路由过程、应用进入前后台等场景

onBackPress:当用户点击返回按钮时触发。

组件生命周期

被@Component装饰的自定义组件的生命周期

aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行。

aboutToDisappear:在自定义组件即将析构销毁时执行。

onAppear:是每个组件的属性方法,在该组件显示时触发此回调。

设备信息

屏幕信息

ts 复制代码
// 获取屏幕分辨率
getDisplayInfo() {
  // 获取默认显示器
  const defaultDisplay = display.getDefaultDisplaySync()
  // 获取屏幕高度
  this.displayHeight = defaultDisplay.height
  // 获取屏幕宽度
  this.displayWidth = defaultDisplay.width
  // 获取屏幕刷新率
  this.displayRefreshRate = defaultDisplay.refreshRate
  // 获取像素密度
  this.displayDensityDPI = defaultDisplay.densityDPI
}

在使用previewer获取到的信息都是0,所以在开发的时候先设定定值

ts 复制代码
// private  deviceWidth:number = display.getDefaultDisplaySync().width;
// private  deviceHeight:number = display.getDefaultDisplaySync().height;

private  deviceWidth:number = 1080;
private  deviceHeight:number = 2340;

网络状态

网络权限

在module.json5中配置网络权限

ts 复制代码
 "requestPermissions": [
      {
        "name": "ohos.permission.GET_NETWORK_INFO"// 获取网络信息权限
      }
    ],

IP

ts 复制代码
//获取 IP 地址
getIPAddress() {
  // 获取默认网络
  const netHandle = connection.getDefaultNetSync()
  // 获取网络连接信息
  const connectionProperties = connection.getConnectionPropertiesSync(netHandle)
  // 提取链路信息
  const linkAddress = connectionProperties.linkAddresses?.[0]
  if (linkAddress) {
    // 提取 IP 地址
    this.IPAddress = linkAddress.address.address
  }
}

网络类型

ts 复制代码
// 获取网络类型
getConnection() {
  const hasDefaultNet = connection.hasDefaultNetSync() // 是否有默认网络
  // 没有网络
  if (!hasDefaultNet) {
    this.netBearType = '无网络连接'
  } else {
    this.getConnectionNetBearType()
  }
}

// 获取网络类型
getConnectionNetBearType() {
  // 1. 获取默认网络
  const defaultNet = connection.getDefaultNetSync()
  // 2. 获取网络能力信息
  const netCapabilities = connection.getNetCapabilitiesSync(defaultNet)
  // 3. 判断网络类型
  if (netCapabilities.bearerTypes.includes(connection.NetBearType.BEARER_ETHERNET)) {
    this.netBearType = '以太网网络'
  } else if (netCapabilities.bearerTypes.includes(connection.NetBearType.BEARER_WIFI)) {
    this.netBearType = 'WIFI网络'
  } else if (netCapabilities.bearerTypes.includes(connection.NetBearType.BEARER_CELLULAR)) {
    this.netBearType = '蜂窝网络'
  }
}
相关推荐
努力变厉害的小超超3 小时前
ArkTS中的组件基础、状态管理、样式处理、class语法以及界面渲染
笔记·鸿蒙
fanstuck19 小时前
互联网技术净土?原生鸿蒙开启全新技术征程
华为·harmonyos·鸿蒙·鸿蒙系统
小蘑菇20181 天前
鸿蒙-promptAction.showToast基于PC屏幕底部提示
harmonyos·鸿蒙
ssslar1 天前
Harmony OS 如何实现 C++ NATIVE YUV420(其他数据格式如BGRA等)自渲染
华为·harmonyos·鸿蒙·openharmony
LCFliu1 天前
13-鸿蒙开发中的综合实战:华为登录界面
前端·华为·harmonyos·鸿蒙·鸿蒙系统
lqj_本人3 天前
Flutter&鸿蒙next中的按钮封装:自定义样式与交互
flutter·华为·harmonyos·鸿蒙
lqj_本人3 天前
Flutter&鸿蒙next中的表单封装:提升开发效率与用户体验
华为·harmonyos·鸿蒙
长弓三石3 天前
鸿蒙网络编程系列42-仓颉版域名解析示例
网络·华为·harmonyos·鸿蒙
LexinZong4 天前
Harmony OS搭建广告展示页
开发语言·鸿蒙