基于HarmonyOS ArkUI 3.0 框架,我成功开发了流式布局网络语 原创 精华

发布于 2021-10-28 12:17
浏览
6收藏

一, 前言

    在介绍之前,吐槽一下为什么文档Ets组件里没有文本输入框,这么基础的组件都不先提供的,好的当时在HDC大会体验Ets实例时,见到有用输入框,名叫TextInput,在开发工具是没有提示的,然后我也尝试用它来为我的Demo提供输入,然而发现个问题,当我把TextInput组件里的text属于绑定@State 定义变量时,每次在文本框输入内容,点击按钮,清空变量值,这时文本输入框也清空了,但当我再次输入内容时,输入文本框会追加上次的内容,估计是因为TextInput有这个Bug,所以还没有在文档上显示出来。

    简单介绍一下本文的实现效果,在文本输入框输入流行网络用语,点击新增按钮,把流行网络用语添加到下面流式布局的组件里,文以x、y轴缩放从0.5变化到1,透明度从0到1 显示出来,点击随机删除按钮时,从下面流行网络用语中随机删除一个,并且以沿y轴旋转360度消失。

二, 实现效果
基于HarmonyOS ArkUI 3.0 框架,我成功开发了流式布局网络语-开源基础软件社区
基于HarmonyOS ArkUI 3.0 框架,我成功开发了流式布局网络语-开源基础软件社区

三, 创建工程

    在这当作你已经安装好最新版本DevEco-Studio开发工具, 点击File -> New -> New Project… 弹出Create HarmonyOS Project窗口, 这里我选择空白eTS模板创建, 下来就跟着一起玩转HarmonyOS ArkUI 3.0 框架声明式开发吧.
基于HarmonyOS ArkUI 3.0 框架,我成功开发了流式布局网络语-开源基础软件社区
基于HarmonyOS ArkUI 3.0 框架,我成功开发了流式布局网络语-开源基础软件社区

四, 界面开发

    界面有三个组件组合而成,文本输入框和新增按钮组合成一个自定义组件, 历史记录和随机删除按钮组合成一个自定义组件,滚动组件和多个文本组件组合成一个自定义组件,下面我们分别从上到下来介绍自定义组件:

@Entry
@Component
struct Search_FlowLayout {
  @State historyArr:string[] = ["人生如戏", "养猪才洋气", "忍为高", "牢房不倒我不学好", "你带着钱", "我消极对待减肥", "宁可高傲的发霉", "接下来的不是故事就是事故", "脚踏实地的干", "可是用钱却买不到", "拍脑袋决策", "笑完我就去睡觉", "有钱的都是大爷","但是欠钱不还的更是"]

  build() {
    Column() {
      // 文本输入框和新增按钮组合自定义组件
      Search_Input({historyArr: $historyArr})
      // 历史记录和随机删除按钮组合成自定义组件
      Clear_History({historyArr: $historyArr})
      // 滚动组件和多个文本组件组合成自定义组件
      Flowlayout_Container({historyArr: $historyArr})
    }
    .alignItems(HorizontalAlign.Center)
  }
}

    实现组件内转场动效,通过点击新增按钮或随机删除按钮来控制Text组件的添加和移除,呈现容器组件子组件添加和移除时的动效。
    这里用到组件转场动画,简单说一下组件转场主要通过transition属性方法配置转场参数,在组件添加和移除时会执行过渡动效,需要配合animteTo才能生效。动效时长、曲线、延时跟随animateTo中的配置。

  1. 文本输入框和新增按钮组合,在新增按钮的onClick事件中添加animateTo方法,来使下面Text子组件动效生效。
@Component
struct Search_Input {
  // 存储文本输入框内容
  @State historyInput: string = ''
  // 链接主入口历史记录数组
  @Link historyArr: string[]

  build() {
    // Flex布局,居中显示
    Flex({ alignItems: ItemAlign.Center }){
      // 文本输入框
      TextInput({ placeholder: '请输入...', text: this.historyInput })
        .type(InputType.Normal)
        .placeholderColor(Color.Gray)
        .placeholderFont({ size: 50, weight: 2})
        .enterKeyType(EnterKeyType.Search)
        .caretColor(Color.Green)
        .layoutWeight(8)
        .height(40)
        .borderRadius('20px')
        .backgroundColor(Color.White)
        .onChange((value: string) => {
          this.historyInput = value
        })

      // 新增网络用语按钮
      Button({type: ButtonType.Capsule, stateEffect:false}) {
        Text('新增').fontSize(17).fontColor(Color.Blue)
      }
      .layoutWeight(2)
      .backgroundColor('#00000000')
      .onClick((event: ClickEvent) => {
        if (this.historyInput != null && this.historyInput.length > 0) {
          // 添加animateTo方法,来使Text组件子组件动效生效
          animateTo({ duration: 600 }, () => {
            this.historyArr.unshift(this.historyInput)
          })
        }
        this.historyInput = ''
      })
    }
    .height(60)
    .padding({left: 10})
    .backgroundColor('#FFedf2f5')
  }
}
  1. 历史记录和随机删除按钮组合
@Component
struct Clear_History {
  // 链接主入口历史记录数组
  @Link historyArr: string[]

  build() {
    Flex({ alignItems: ItemAlign.Center }) {
      if (this.historyArr.length > 0) {
        Text('历史记录')
          .fontSize(14)
          .fontColor(Color.Grey)
          .layoutWeight(5)

        Text('随机删除')
          .textAlign(TextAlign.End)
          .margin({right: 30})
          .fontSize(14)
          .fontColor(Color.Red)
          .layoutWeight(5)
          .onClick((event: ClickEvent) => {
            // 添加animateTo方法,来使Text组件子组件动效生效
            // 随机从历史记录删除一个
            animateTo({ duration: 600 }, () => {
              var idx = Math.floor(Math.random()*this.historyArr.length);
              this.historyArr.splice(idx, 1)
            })
          })
      }
    }
    .height(40)
    .padding({ left: 20, top: 10 })
  }
}
  1. 滚动组件和多个文本组件组合成, 给Text组件添加两个transition属性,分别用于定义组件的添加动效和移除动效。
@Component
struct Flowlayout_Container {
  // 链接主入口历史记录数组
  @Link historyArr: string[]

  build() {
    // 滚动组件
    Scroll() {
      // Flex布局, wrap为FlexWrap.Wrap为流式布局
      Flex({justifyContent: FlexAlign.Start, wrap: FlexWrap.Wrap}) {
        if (this.historyArr.length > 0) {
          // 循环显示出网络用语到文本组件
          ForEach(this.historyArr,
            (item:string) => {
              Text(`${item}`)
                .fontSize(18)
                .borderStyle(BorderStyle.Solid)
                .borderWidth('1px')
                .borderColor('#dddddd')
                .borderRadius('90px')
                .padding({top: 4, bottom: 4, right: 10, left: 10})
                .margin({top: 10, right: 10})
                .textOverflow({overflow: TextOverflow.Ellipsis})
                .maxLines(2)
                // 新增网络用语时的动画
                .transition({ type: TransitionType.Insert, scale: { x: 0.5, y: 0.5 }, opacity: 0 })
                // 随机删除网络用语的动画
                .transition({ type: TransitionType.Delete, rotate: { x: 0, y: 1, z: 0, angle: 360 }, scale: { x: 0, y: 0 } })
            },
            (item:string) => item.toString()
          )
        }
      }
      .margin({left: 20, right: 10, bottom: 100})
      .padding({bottom: 10})
    }
  }
}

介绍就到此了,声明式开发,是不是简洁了很多,大家一起撸起来吧。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
12
收藏 6
回复
举报
回复
添加资源
添加资源将有机会获得更多曝光,你也可以直接关联已上传资源 去关联
    相关推荐