开源 Arkts 鸿蒙应用 开发(五)控件组成和复杂控件

文章的目的为了记录使用Arkts 进行Harmony app 开发学习的经历。本职为嵌入式软件开发,公司安排开发app,临时学习,完成app的开发。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。

相关链接:

开源 Arkts 鸿蒙应用 开发(一)工程文件分析-CSDN博客

开源 Arkts 鸿蒙应用 开发(二)封装库.har制作和应用-CSDN博客

开源 Arkts 鸿蒙应用 开发(三)Arkts的介绍-CSDN博客

开源 Arkts 鸿蒙应用 开发(四)布局和常用控件-CSDN博客

开源 Arkts 鸿蒙应用 开发(五)控件组成和复杂控件-CSDN博客

推荐链接:

开源 java android app 开发(一)开发环境的搭建-CSDN博客

开源 java android app 开发(二)工程文件结构-CSDN博客

开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客

开源 java android app 开发(四)GUI界面重要组件-CSDN博客

开源 java android app 开发(五)文件和数据库存储-CSDN博客

开源 java android app 开发(六)多媒体使用-CSDN博客

开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客

开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客

开源 java android app 开发(九)后台之线程和服务-CSDN博客

开源 java android app 开发(十)广播机制-CSDN博客

开源 java android app 开发(十一)调试、发布-CSDN博客

开源 java android app 开发(十二)封库.aar-CSDN博客

推荐链接:

开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客

开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客

开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客

开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-CSDN博客

开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客

本章节内容如下:

  1. 控件组成分析

  2. 页面的跳转

  3. 复杂控件

一、控件的组成分析

1.1控件的组成

装饰器: 用于装饰类、结构、方法以及变量,并赋予其特殊的含义。如上述示例中@Entry、@Component和@State都是装饰器,@Component表示自定义组件,@Entry表示该自定义组件为入口组件,@State表示组件中的状态变量,状态变量变化会触发UI刷新。

UI描述:以声明式的方式来描述UI的结构,例如build()方法中的代码块。

自定义组件:可复用的UI单元,可组合其他组件,如上述被@Component装饰的struct Hello。

系统组件:ArkUI框架中默认内置的基础和容器组件,可以直接调用,例如示例中的Column、Text、Divider、Button。

属性方法:组件可以通过链式调用配置多项属性,如fontSize()、width()、height()、backgroundColor()等。

事件方法:组件可以通过链式调用设置多个事件的响应逻辑,如跟随在Button后面的onClick()

1.2 控件配置属性

配置组件的多个属性。

复制代码
Image('test.jpg')
  .alt('error.jpg')    
  .width(100)    
  .height(100)

除了直接传递常量参数,还可以传递变量或表达式

复制代码
Text('hello')
  .fontSize(this.size)
Image('test.jpg')
  .width(this.count % 2 === 0 ? 100 : 200)    
  .height(this.offset + 100)

1.3 控件配置事件

使用箭头函数配置组件的事件方法

复制代码
Button('Click me')
  .onClick(() => {
    this.myText = 'ArkUI';
  })

使用组件的成员函数配置组件的事件方法,需要bind this。ArkTS语法不建议使用成员函数配合bind this来配置组件的事件方法

复制代码
myClickHandler(): void {
  this.counter += 2;
}
...
Button('add counter')
  .onClick(this.myClickHandler.bind(this))

使用声明的箭头函数时可以直接调用,不需要bind this。

复制代码
fn = () => {
  console.info(`counter: ${this.counter}`)
  this.counter++
}
...
Button('add counter')
  .onClick(this.fn)

1.4 控件的循环渲染

ArkUI通过自定义组件的build()函数和@Builder装饰器中的声明式UI描述语句构建相应的UI。在声明式描述语句中开发者除了使用系统组件外,还可以使用渲染控制语句来辅助UI的构建,这些渲染控制语句包括控制组件是否显示的条件渲染语句,基于数组数据快速生成组件的循环渲染语句,针对大数据量场景的数据懒加载语句,针对混合模式开发的组件渲染语句。

复制代码
@Entry
@Component
struct MyComponent {
  @State count: number = 0;


  build() {
    Column() {
      Text(`count=${this.count}`)


      if (this.count > 0) {
        Text(`count is positive`)
          .fontColor(Color.Green)
      }


      Button('increase count')
        .onClick(() => {
          this.count++;
        })


      Button('decrease count')
        .onClick(() => {
          this.count--;
        })
    }
  }
}


@Entry
@Component
struct Parent {
  @State simpleList: Array<string> = ['one', 'two', 'three'];


  build() {
    Row() {
      Column() {
        ForEach(this.simpleList, (item: string) => {
          ChildItem({ item: item })
        }, (item: string) => item)
      }
      .width('100%')
      .height('100%')
    }
    .height('100%')
    .backgroundColor(0xF1F3F5)
  }
}


@Component
struct ChildItem {
  @Prop item: string;


  build() {
    Text(this.item)
      .fontSize(50)
  }
}

二、页面的跳转,实现了从index页面跳转到pageone页面的功能

Router路由的页面是一个@Entry修饰的Component,每一个页面都需要在main_page.json中声明。

main_page.json代码

复制代码
// main_page.json
{
  "src": [
    "pages/Index",
    "pages/pageOne",
    
  ]
}

index.etsd代码

复制代码
// index.ets
import { router } from '@kit.ArkUI';


@Entry
@Component
struct Index {
  @State message: string = 'Hello World';


  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        Button('router to pageOne', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.getUIContext().getRouter().pushUrl({
              url: 'pages/pageOne' // 目标url
            }, router.RouterMode.Standard, (err) => {
              if (err) {
                console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);
                return;
              }
              console.info('Invoke pushUrl succeeded.');
            })
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

pageone.ets代码

复制代码
// pageOne.ets
import { router } from '@kit.ArkUI';


@Entry
@Component
struct pageOne {
  @State message: string = 'This is pageOne';


  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        Button('router back to Index', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.getUIContext().getRouter().back();
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

三、复杂控件

3.1 选项卡,鸿蒙的选项卡编程比安卓确实方便了许多

下面为代码

复制代码
import  {MainPage} from 'library'
@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  build() {
//Tabs({ barPosition: BarPosition.End }),使用这句设置为底部
    Tabs() { 

      TabContent() {
        Text('首页的内容').fontSize(30)
      }
      .tabBar('首页')


      TabContent() {
        Text('推荐的内容').fontSize(30)
      }
      .tabBar('推荐')


      TabContent() {
        Text('发现的内容').fontSize(30)
      }
      .tabBar('发现')

      TabContent() {
        Text('我的内容').fontSize(30)
      }
      .tabBar("我的")
    }
  }
}

以下为显示效果

3.2 listview

index.ets代码

复制代码
import { router } from '@kit.ArkUI';


@Entry
@Component
struct Index {
  // 列表数据 - 字符串数组
  private dataList: string[] = [
    "苹果",
    "香蕉",
    "橙子",
    "西瓜",
    "葡萄",
    "芒果",
    "草莓"
  ];

  build() {
    Column() {
      // 列表标题
      Text('水果列表')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 20, bottom: 10 })

      // ListView 实现
      List({ space: 10 }) {
        ForEach(this.dataList, (item: string) => {
          ListItem() {
            Text(item)
              .fontSize(18)
              .width('100%')
              .height(60)
              .textAlign(TextAlign.Center)
              .backgroundColor(Color.White)
              .borderRadius(8)
          }
          .onClick(() => {
            // 点击跳转到详情页,传递当前项内容
            router.push({
              url: 'pages/page1',
              params: {
                content: item  // 传递字符串内容
              }
            });
          })
        })
      }
      .width('100%')
      .layoutWeight(1)  // 占据剩余空间
      .margin(10)
      .divider({
        strokeWidth: 1,
        color: '#EEEEEE',
        startMargin: 20,
        endMargin: 20
      })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
  }
}

Page1.ets代码

复制代码
import { router } from '@kit.ArkUI';


@Entry
@Component
struct DetailPage {
  // 接收的内容状态
  @State private receivedContent: string = '';

  // 页面显示时获取路由参数
  onPageShow() {
    const params = router.getParams();
    console.log("test"+ params.toString());
    /*
    if (params && params['content']) {
      this.receivedContent = String(params['content']);
    } else {
      this.receivedContent = '未接收到内容';
    }
    * */
  }

  build() {
    Column({ space: 20 }) {
      // 页面标题
      Text('详情页面')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 20 })

      // 内容显示区域
      Column() {
        Text('接收到的内容:')
          .fontSize(18)
          .fontColor('#666')
          .margin({ bottom: 10 })

        Text(this.receivedContent)
          .fontSize(20)
          .fontWeight(FontWeight.Medium)
          .fontColor('#409EFF')
      }
      .width('90%')
      .padding(20)
      .backgroundColor(Color.White)
      .borderRadius(12)
      .shadow({ radius: 6, color: '#00000020', offsetX: 2, offsetY: 4 })

      // 返回按钮
      Button('返回')
        .width(120)
        .height(40)
        .fontSize(16)
        .margin({ top: 30 })
        .onClick(() => {
          router.back();
        })
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .backgroundColor('#F8F8F8')
    .justifyContent(FlexAlign.Center)
  }
}

程序运行的效果

相关推荐
liuhaikang4 小时前
我做个一个APP叫【图影工具箱】:一站式解决视频提取音频和加水印的鸿蒙神器
harmonyos
alex88865 小时前
介绍一款免费MES、开源MES系统、MES源码
java·5g·开源·产品运营·软件构建·制造·源代码管理
谢道韫6665 小时前
鸿蒙组件通用事件开发全攻略:从基础交互到工程实践
microsoft·交互·harmonyos
TDengine (老段)6 小时前
TDengine 集群超能力:超越 InfluxDB 的水平扩展与开源优势
大数据·数据库·开源·时序数据库·iot·tdengine·涛思数据
1688red7 小时前
IPv4编址及IPv4路由基础
运维·网络·华为
呆dai~7 小时前
基于原生能力的键盘控制
harmonyos·鸿蒙
QiYueFangBeiJing8 小时前
内网运行控制四百来个海康威视硬件物联网定员管控软件(华为平板电脑版)
物联网·华为·电脑
Sally璐璐9 小时前
HarmonyOS开发利器:ArkTS全解析
华为·harmonyos