记在前面
因无法直接使用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 = '蜂窝网络'
}
}