HarmonyOS ArkUI基础学习01

以下涉及的项目源码地址: https://gitee.com/jiangqianghua/harmony-test
更多学习资源资源点我获取

1. 一些常用组件方法

  1. 加载resource/base/element/string.json资源
Text($r("app.string.Username_label"))
  1. 设置颜色
    1. Color.red
    2. “#ff00ff”
    3. 读取资源文件字体颜色 resource/base/element/color.json
.backgroundColor(Color.Red)
.backgroundColor("#00ff00")
.backgroundColor($r("app.color.start_window_background"))
  1. 超出显示省略号
Text('11222222222222333333333333333333333344')
    .fontSize(20)
    .textOverflow({overflow: TextOverflow.Ellipsis})
    .maxLines(1)
    .width(100)
  1. Button形状
    1. 默认形状
    Button('按钮')
          .type(ButtonType.Normal)  // 矩形
          // .type(ButtonType.Circle) // 圆形
          // .type(ButtonType.Capsule) // 胶囊
2. 自定义按钮,使用插槽方式
   Button(){
          Row(){
            LoadingProgress().width(50).height(50).color(Color.White)
            Text('登录').fontColor(Color.White)
          }
        }.width(120)
  1. CheckBox使用
Row(){
    CheckboxGroup({group: 'favor'})
    .selectedColor(Color.Red)
    .height(0)
    .onChange((value) => {
        console.log(JSON.stringify(value))
    })
    Text("全选/全不选")
    }
    Row(){
        Row(){
            Checkbox({group: 'favor', name: '1'})
            Text('篮球')
        }
        Row(){
            Checkbox({group: 'favor', name: '2'})
            Text('足球')
        }
        Row(){
            Checkbox({group: 'favor', name: '3'})
            Text('乒乓球')
        }
    }
  1. Radio组件
 Row(){
          Row(){
            Radio({group: 'favor', value: '1'})
              .onChange((value) => {
                value && console.log('1')
              })
            Text('篮球')
          }
          Row(){
            Radio({group: 'favor', value: '2'})
              .onChange((value) => {
                value && console.log('2')
              })
            Text('足球')
          }
        }
  1. Toggle组件
Row(){
    Toggle({
    type: ToggleType.Switch,
    isOn: false
    }).selectedColor(Color.Red)
    Toggle({
    type: ToggleType.Button,
    isOn: false
    }){
    Text('选择')
    }.selectedColor(Color.Red)
    Toggle({
    type: ToggleType.Checkbox,
    isOn: false
    }).selectedColor(Color.Red)
}
  1. Image
    // ets/images/a.jpg
    Image("images/a.jpg")
          .width(100)
   Image($r("app.media.icon"))
          .width(100)
          // 小图片是否有锯齿
          .interpolation(ImageInterpolation.High)
        // 需要访问网络权限 在modules.json5 下
        //    "requestPermissions": [
        //   {
        //     "name": "ohos.permission.INTERNET"
        //   }
        // ],
    Image("url")
          .width(100)
    
    Image($r("app.media.icon"))
            .objectFit(ImageFit.Auto)
        // 是否重复
        .objectRepeat(ImageRepeat.XY)
        // 黑白显示
        .renderMode(ImageRenderMode.Template)
        .width(100)
        // 是否有锯齿,插值
        .interpolation(ImageInterpolation.High)
        .onComplete((value) => {
        console.log(JSON.stringify(value))
        //{"width":114,"height":114,"componentWidth":300,"componentHeight":300,"loadingStatus":1}
        })

2. 像素单位

  1. px 物理像素
  2. vp 屏幕密度像素单位,虚拟像素 1vp约等于3px, 默认单位
  3. fp 字体像素
  4. lpx 视图逻辑像素单位,等比缩放,默认是720,1lpx为2px大小, 场景,根据ui稿高度还原使用
    lpx 默认值可以修改,修改在resource/base/profiles/main_pages.json
  "window": {
    "designWidth": 1440  // 1lpx = 1px, 如果屏幕真实是1280, 那么设置1440,也是撑满
  }
  1. 单位转换
    1. vp2px
    2. px2vp
    3. fp2vp
    4. px2fp
    5. lpx2px

3. 线性布局

    // space 子元素间距
  Row({space: 10}){
          Text('111').layoutWeight(1).backgroundColor(Color.Red)
          Text('222').layoutWeight(1).backgroundColor(Color.Red)
          Text('333').layoutWeight(1).backgroundColor(Color.Red)
        }

4. 空白填充组件,把空余空间占满

Blank()

5. 层叠布局

 Stack(){
  Text("111").width(200).height(200).backgroundColor(Color.Red)
    // 设置层级
    .zIndex(2)
  Text("111").width(100).height(100).backgroundColor(Color.Yellow)
}.width('100%').height(300).backgroundColor(Color.Grey)
// 控制对齐位置
.alignContent(Alignment.TopStart)

6. 获取List控制器

  private scroll: Scroller = new Scroller();
  ...
  List({scroller: this.scroll})

7. 弹性布局flex

  Flex({
    direction: FlexDirection.Row,
    justifyContent: FlexAlign.Center,
    // Stretch 拉伸
    // Baseline 文本基线对其
    alignItems: ItemAlign.Center
  }){
    Text("111").backgroundColor(Color.Blue).width(100).height(100)
    Text("222").backgroundColor(Color.Pink).width(200).height(200)
    Text("333").backgroundColor(Color.Brown).width(200).height(200)
      // 孩子单独交叉轴设置
      .alignSelf(ItemAlign.Start)
  }.width('100%').height(300).backgroundColor(Color.Gray)

  Flex({
    direction: FlexDirection.Row,
    justifyContent: FlexAlign.Start,
    // Stretch 拉伸
    // Baseline 文本基线对其
    alignItems: ItemAlign.Center,
    // 自动换行
    wrap: FlexWrap.Wrap
  }){
    Text("111").backgroundColor(Color.Blue).width(400).height(100)
    Text("222").backgroundColor(Color.Pink).width(100).height(100)
    Text("333").backgroundColor(Color.Brown).width(100).height(100)
    // 压缩比例
    .flexShrink(2)
    // 设置权重,瓜分剩余空间
    .flexGrow(1)
  }.width('100%').height(300).backgroundColor(Color.Gray)

8. 栅格布局GridRow 和 GridCol

  1. 解决不同尺寸,动态布局的问题
  2. 支持 xs(<320vp),sm(320-520), md(520-840), lg(840-1080), xl(>1080), xxl 断点
GridRow({
    // 排列方向
    // direction: GridRowDirection.RowReverse,
    // 间距
    gutter: 10,
    // columns 和下面span意思是一样,但是xs:1 表示小屏是一列
    columns: {xs:1, sm: 2, md: 4, lg: 6, xl: 8},
    breakpoints: {value: ['200vp', '300vp', '400vp', '500vp', '600vp']}
  }){
    ForEach(this.bgColors, (item, index) => {
      GridCol({
        // 默认12栅格,然后按照, xs:12 表示在超小屏幕,一个col就占12栅格
        // span: {xs:12, sm: 6, md: 4, lg: 3, xl: 2}
      }){
        Row(){
          Text(`${index + 1}`)
        }.width('100%').height('50')
        .backgroundColor(item)
      }
      //表示一个col占6栅格,会固定死,会使得上面span不起作用
      // .span(6)
    })
  }

9. 网格布局 Grid

Grid(){
  GridItem(){Text("111")}.style()
  // 横跨2列
  .columnStart(0).columnEnd(1)
  GridItem(){Text("222")}.style()
  // 横跨2行
  .rowStart(0).rowEnd(1)
  GridItem(){Text("333")}.style()
  GridItem(){Text("444")}.style()
  GridItem(){Text("555")}.style()
  GridItem(){Text("666")}.style()
}
.width('100%')
.columnsGap(10)
.rowsGap(10)
.height(200)
.rowsTemplate("1fr 1fr")
.columnsTemplate("1fr 1fr 1fr")

10. 轮播组件

@Entry
@Component
struct Page_Swiper {
  @State message: string = 'Hello World'
  private swiperController: SwiperController = new SwiperController();
  build() {
    Row() {
      Column() {
        Swiper(this.swiperController){
          Text("111").itemStyle().backgroundColor(Color.Red)
          Text("222").itemStyle().backgroundColor(Color.Blue)
          Text("333").itemStyle().backgroundColor(Color.Brown)
        }.loop(false)
        .autoPlay(true)
        .interval(2000)
        .indicatorStyle({
          size: 20,
          left: 0,
          color: Color.White
        })
        .vertical(true)
        .onChange(index => {
          // 获取当前索引
          console.log('index = ' + index)
        })

        Button('click').onClick(() => {
          this.swiperController.showPrevious();
        })
      }
      .width('100%')
    }
    .height('100%')
  }
}

@Extend(Text)
function itemStyle(){
  .width('100%')
  .height(200)
  .textAlign(TextAlign.Center)
  .fontSize(30)
}

11. List布局

@Entry
@Component
struct Page_List {
  @State message: string = 'Hello World'
  @State list: string[] = ['111', '222', '333', '444', '555', '666']
  private listController: Scroller = new Scroller();
  build() {
    Row() {
      Column() {
        List({space: 10, scroller: this.listController}){
          ForEach(this.list, (item, index) => {
            ListItem(){
              Text(item)
            }.width('100%')
            .height(100)
            .backgroundColor(Color.Yellow)
            // 控制每个item内容的位置
            .align(Alignment.Start)
            // 侧滑
            .swipeAction({
              end: this.itemEnd(index)
            })
          })
        }.height(300)
        .width('100%')
        .backgroundColor(Color.Blue)
        // 控制子元素位置
        .alignListItem(ListItemAlign.Center)
        // 滚动方向
        .listDirection(Axis.Vertical)
        // 分割线
        .divider({
          strokeWidth:2,
          startMargin: 10,
          endMargin: 10,
          color: Color.Red
        })
        // 滚动条显示方式
        .scrollBar(BarState.Auto)
        .onScrollIndex((start, end) => {
          if (end === this.list.length - 1) {
            console.log('到底了,加载新数据')
          }
        })
        Button('click').onClick(() => {
          this.listController.scrollToIndex(0)
        })
      }
      .width('100%')
    }
    .height('100%')
  }

  @Builder
  itemEnd(index: number){
    Button('删除').backgroundColor(Color.Red)
  }
}

12. List分组布局

@Entry
@Component
struct Page_List2 {
  @State message: string = 'Hello World'
  @State cityList: Object[] = [
    {
      type: 'A',
      list: ['鞍山', '安顺', '安康']
    },
    {
      type: 'B',
      list: ['北京', '保定', '包头']
    },
    {
      type: 'C',
      list: ['长春', '长沙', '常德']
    }
  ]
  build() {
    Row() {
      Column() {
        List({ space: 10 }) {
          ForEach(this.cityList, item => {
            ListItemGroup({header: this.header(item.type)}){
              ForEach(item.list, data => {
                ListItem(){
                  Text(data)
                }
                .align(Alignment.Start)
                .width('100%')
                .height(100)
              })
            }
          })
        }
        .height(300)
        .width('100%')
        // 粘性
        .sticky(StickyStyle.Header)
      }
      .width('100%')
    }
    .height('100%')
  }

  @Builder
  header(type: string) {
    Text(type).fontSize(30)
  }
}

13 Tabs容器,组件导航

@Entry
@Component
struct Page_Tabs {
  @State message: string = 'Hello World'
  build() {
    Row() {
      Column() {
        Tabs({
          // 导航位置
          barPosition: BarPosition.Start
        }){
          TabContent(){
            Text('电影列表').fontSize(30)
          }.tabBar('电影')
          TabContent(){
            Text('影院列表').fontSize(30)
          }.tabBar('影院')
          TabContent(){
            Text('个人中心').fontSize(30)
          }.tabBar('我的')
        }
        // 当tab较多,可以设置滑动显示
        .barMode(BarMode.Scrollable)
        // 阻止滑动切换
        .scrollable(false)
        // 滚动方向
        // .vertical(true)
        // .barWidth(100)
        // .barHeight(200)
      }
      .width('100%')
    }
    .height('100%')
  }
}

14. 自定义导航

@Entry
@Component
struct Page_Tabs {
  @State message: string = 'Hello World'
  @State currentIndex: number = 0
  private tabbarController: TabsController = new TabsController();
  @Builder
  tabbarItem(title: string, icon: Resource, selectedIcon: Resource, index: number){
    Column(){
      Image(this.currentIndex === index ? selectedIcon : icon).size({width: 25, height: 25})
      Text(title).fontColor(this.currentIndex === index ? Color.Red : Color.Black)
    }
    .width('33.33%')
    .height(50)
  }
  build() {
    Row() {
      Column() {
        Tabs({
          controller: this.tabbarController,
          // 导航位置
          barPosition: BarPosition.End
        }){
          TabContent(){
            Text('电影列表').fontSize(30)
          }.tabBar(this.tabbarItem('电影', $r("app.media.icon"), $r("app.media.icon"), 0))
          TabContent(){
            Text('影院列表').fontSize(30)
          }.tabBar(this.tabbarItem('影院', $r("app.media.icon"), $r("app.media.icon"), 1))
          TabContent(){
            Text('个人中心').fontSize(30)
          }.tabBar(this.tabbarItem('我的', $r("app.media.icon"), $r("app.media.icon"), 2))
        }
        .onChange((index) => {
          this.currentIndex = index
        })
        // 当tab较多,可以设置滑动显示
        .barMode(BarMode.Scrollable)
        // 阻止滑动切换
        // .scrollable(false)
        // 滚动方向
        // .vertical(true)
        // .barWidth(100)
        // .barHeight(200)
      }
      .width('100%')
    }
    .height('100%')
  }
}

15. Navigation布局

@Entry
@Component
struct Page_Nav {
  @State message: string = 'Hello World'
  @State list:Object[] = [
    {
      title: '111',
      content: '111'
    },
    {
      title: '222',
      content: '222'
    },
    {
      title: '333',
      content: '333'
    }
  ]
  build() {
    Navigation(){
      List(){
        ForEach(this.list, item => {
          ListItem(){
            // 可以很好的自适应大屏显示
            NavRouter(){
              Text(item.title)
                .width('100%')
                .height(70)
                .backgroundColor(Color.White)
                .borderRadius(25)
                .fontSize(20)
                .textAlign(TextAlign.Center)
              NavDestination(){
                Text(item.content)
                  .width('100%')
                  .height('100%')
                  .backgroundColor(Color.White)
              }.title(item.title)
              .backgroundColor(Color.White)
            }
          }
        })
      }
    }
    .menus([{
      value: "",
      icon: './images/a.jpg',
      action: () => {
        console.log("search")
      }
    }])
    .toolBar({
      items: [
        {
          value: "笔记",
          icon: './images/a.jpg',
          action: () => {
            console.log("search")
          }
        },
        {
          value: "待办",
          icon: './images/a.jpg',
          action: () => {
            console.log("search")
          }
        }
      ]
    })
    .title('全部笔记')
    .height('100%')
    .width('100%')
    .titleMode(NavigationTitleMode.Mini)
    .backgroundColor(Color.White)
    // 显示方式
    .mode(NavigationMode.Auto)
  }
}

15. 页面动画

  1. 页面内的动画
    1. 属性动画
// 属性动画
@Entry
@Component
struct Page_Animation2 {
  @State message: string = 'Hello World'
  @State myWidth: number = 100
  build() {
    Row() {
      Column() {
        Button('显式动画').onClick(() => {
          this.myWidth = 200
        })
        Text(this.message)
          .width(this.myWidth)
          .height(100)
          .backgroundColor(Color.Grey)
          .animation({duration: 1000, curve: Curve.Linear})
      }
      .width('100%')
    }
    .height('100%')
  }
}
  1. 显示动画
@Entry
@Component
struct Page_Animation {
  @State message: string = 'Hello World'
  @State myWidth: number = 100
  @State list: string[] = ['1111', '2222', '33333', '44444']
  build() {
    Row() {
      Column() {
        Button('显式动画').onClick(() => {
          animateTo({duration: 1000, curve: Curve.Ease}, () => {
            this.myWidth = 200
          })
        })
        Text(this.message)
          .width(this.myWidth)
          .height(100)
          .backgroundColor(Color.Grey)

        List(){
          ForEach(this.list, (item, index)=>{
            ListItem(){
              this.item(item, index)
            }
          })
        }.backgroundColor(Color.Blue)
      }
      .width('100%')
    }
    .height('100%')
  }

  @Builder
  item(item: string, index: number) {
    Row(){
      Text(item)
      Button('del').onClick(()=>{
        animateTo({duration: 1000, curve: Curve.Linear}, ()=>{
          this.list.splice(index, 1)
        })
      })
    }
  }
}
  1. 组件内转场动画
@Entry
@Component
struct Page_Animation3 {
  @State message: string = 'Hello World'
  @State isShow: boolean = true
  @State list: string[] = ['1111', '2222', '33333', '44444']
  build() {
    Row() {
      Column() {
        // Column(){
        //   Button('折叠/展开').onClick(()=> {
        //     animateTo({duration: 1000, curve: Curve.Linear}, ()=>{
        //       this.isShow = !this.isShow
        //     })
        //   })
        //   if (this.isShow) {
        //     Text('侧边栏')
        //       .width(200)
        //       .height(100)
        //       .backgroundColor(Color.Blue)
        //       .transition({
        //         type: TransitionType.All,
        //         translate: {x: -200, y: 0},
        //         opacity: 0
        //       })
        //   }
        // }.width("100%")
        // .height(300)
        // .backgroundColor(Color.Grey)
        // .alignItems(HorizontalAlign.Start)
      }
      List(){
        ForEach(this.list, (item, index)=>{
          ListItem(){
            this.item(item, index)
          }.transition({
            type: TransitionType.Delete,
            translate: {x: 200},
            scale: {x:0, y: 0}
          }).transition({
            type: TransitionType.Insert,
            translate: {y: 100}
          })
        }, item=>item)
      }.backgroundColor(Color.Blue)
      .width('100%')
      .height(400)
    }
    .height('100%')
  }

  @Builder
  item(item: string, index: number) {
    Row(){
      Text(item)
      Button('del').onClick(()=>{
        animateTo({duration: 1000, curve: Curve.Linear}, ()=>{
          this.list.splice(index, 1)
        })
      })
    }
  }
}
  1. 页面间动画
    1. 共享元素转场动画
    2. 页面转场动画
// a页面
  pageTransition(){
    PageTransitionExit({ type: RouteType.Push, duration: 1000 }).slide(SlideEffect.Left)
    PageTransitionEnter({ type: RouteType.Pop, duration: 1000 }).slide(SlideEffect.Left)
  }

  // b页面
  pageTransition(){
    PageTransitionExit({ type: RouteType.Push, duration: 1000 }).slide(SlideEffect.Right)
    PageTransitionEnter({ type: RouteType.Pop, duration: 1000 }).slide(SlideEffect.Right)
  }

16. divider 用法

 .divider({
    strokeWidth: $r('app.float.divider_stroke_width'),
    color: $r('app.color.item_divider')
  })

你可能感兴趣的:(IT资源,harmonyos,学习,华为,ui,前端,android)