鸿蒙开发Day01

rxlxr的博客

结果展示

使用PlanA和PlanB来实现自定义组件,PlanA较为繁琐,但能成功实现浮动输入框效果,PlanB简单但无法触发onFocus等事件,若有大佬知道如何解决该问题可以指导我一下。
在这里插入图片描述

PlanA

自定义Label类

由于ArkTS没有label组件,所以自定义一个label类,当输入框onFocus时,label字体缩小并上移。

起初只定义了文本、字体大小、位置三个属性变量,如果这样定义,其他页面导入自定义组件时,无法灵活更改标签属性。故为了提高代码的灵活性,定义了在输入框不同状态时标签的文本、字体大小、位置,如此让代码显得有些复杂。其他组件或页面使用该类创建对象时可读性也大大降低。

创建对象
username_label = new rxLabel('Username',25,20,40,30,40,5)
Label定义
export class rxLabel {
  Text: string;
  FontSize: number;

  FontSize_Focus: number;
  FontSize_Blur: number;

  Position_x: number;
  Position_y: number;

  Position_Blur_x: number;
  Position_Blur_y: number;

  Position_Focus_x: number;
  Position_Focus_y: number;

  constructor(text: string,
              fontSize: number, fontSize_focus: number,
              position_x: number, position_y: number,
              position_focus_x: number, position_focus_y: number) {
    this.Text = text

    this.FontSize = fontSize
    this.FontSize_Blur = fontSize
    this.FontSize_Focus = fontSize_focus

    this.Position_Blur_x = position_x
    this.Position_Blur_y = position_y

    this.Position_x = position_x
    this.Position_y = position_y

    this.Position_Focus_x = position_focus_x
    this.Position_Focus_y = position_focus_y
  }

}
自定义Input类

输入框和自带输入框差别不大,只是以标签作为placeholder,当输入框onFocus时,边框颜色改变。label为可选参数。

当输入框onFocus时,调用focus函数,当输入框onBlur时,调用Blur函数。

可选参数函数

如果函数定义了参数则必须传递这些参数否则报错,如果不想传递这些参数,可以添加 ? ,语法如下:

function func_name(param1: paramType, param2?: paramType) {
}
创建对象
username_input = new rxInput(InputType.Normal,'#666666','#6b9d68',this.username_label)
input定义
export class rxInput {
  Label: rxLabel;

  BottomColor: string;

  BottomColor_Blur: string
  BottomColor_Focus: string;

  Type: number;
  Value: string = '';

  constructor(type: number = InputType.Normal, bottomColor: string,
              bottomColor_focus: string, label?: rxLabel)
  {
    this.Type = type
    this.BottomColor = bottomColor
    this.BottomColor_Blur = bottomColor
    this.BottomColor_Focus = bottomColor_focus
    if (label){
      this.Label = label
    }
  }

  focus(fontSize: number, x?: number, y?: number) {

    if (this.Label != null && x != null && y != null){
      this.Label.FontSize = fontSize
      this.Label.Position_x = x
      this.Label.Position_y = y
    }

    this.BottomColor = this.BottomColor_Focus
  }

  blur(fontSize: number, x?: number, y?: number)
  {
    if (this.Label != null && x != null && y != null && this.Value == ''){
      this.Label.FontSize = fontSize
      this.Label.Position_x = x
      this.Label.Position_y = y
    }

    this.BottomColor = this.BottomColor_Blur
  }

}

自定义组件

在创建label和input对象时为组件赋值

ExInput({rx_input:this.username_input})
  1. 使用RelativeContainer或stack等容器达到label和input堆叠的效果
  2. 输入框border四边只设置底边宽度
  3. 使用属性动画达到过渡的效果
源码
@Component
export struct ExInput {
  @State private rx_input : rxInput = null
  build() {
    Column({space: 10}) {
      RelativeContainer() {

        TextInput()
          .id("input")
          .type(this.rx_input.Type)
          .width(350)
          .fontSize(25)
          .aspectRatio(6)
          .backgroundColor('#ffffff')
          .caretColor(Color.Black)
          .border({
            color: this.rx_input.BottomColor,
            width: {
              bottom: 2
            },
            radius: 0,
            style: BorderStyle.Solid
          })
          .alignRules({
            middle: {
              anchor: "__container__",
              align:HorizontalAlign.Center
            },
            bottom: {
              anchor: "__container__",
              align:VerticalAlign.Bottom
            }
          })
          .onChange((value) => {
            this.rx_input.Value = value;
          })
          .onFocus(() => {
            this.rx_input.focus(
              this.rx_input.Label.FontSize_Focus,
              this.rx_input.Label.Position_Focus_x,
              this.rx_input.Label.Position_Focus_y)
          })
          .onBlur(() => {
            this.rx_input.blur(
              this.rx_input.Label.FontSize_Blur,
              this.rx_input.Label.Position_Blur_x,
              this.rx_input.Label.Position_Blur_y)
          })

        Text(this.rx_input.Label.Text)
          .id("label")
          .fontColor('#666666')
          .fontSize(this.rx_input.Label.FontSize)
          .position({
            x: this.rx_input.Label.Position_x,
            y: this.rx_input.Label.Position_y
          })
          .animation({
            duration: 300,
            curve: Curve.Friction,
            playMode: PlayMode.Normal
          })
      }
      .width("100%")
      .height(80)
      .backgroundColor(Color.White)
    }
  }
}

PlanB

设置文本、字体大小、位置、内容、类别、颜色作为属性并设置默认值,在创建组件时为其赋值

TestInput({
          Type: InputType.Normal,
          Text: 'Username',
          FontSize: this.fz,
          BottomColor: this.bc,
          Position_x: this.px,
          Position_y: this.py
        })
源码

@Component
export struct TestInput {

  Text: string;
  FontSize: number = 25;

  Position_x: number = 40;
  Position_y: number = 30;

  BottomColor: string = '#666666';

  Type: number;
  Value: string = '';

  onClick: (event: (event?: ClickEvent) => void) => CommonAttribute;
  onFocus: (event: () => void) => CommonAttribute

  build() {
    Column({space: 10}) {
      RelativeContainer() {
        TextInput()
          .id("input")
          .type(this.Type)
          .width(350)
          .fontSize(25)
          .aspectRatio(6)
          .backgroundColor('#ffffff')
          .caretColor(Color.Black)
          .border({
            color: this.BottomColor,
            width: {
              bottom: 2
            },
            radius: 0,
            style: BorderStyle.Solid
          })
          .alignRules({
            middle: {
              anchor: "__container__",
              align:HorizontalAlign.Center
            },
            bottom: {
              anchor: "__container__",
              align:VerticalAlign.Bottom
            }
          })
          .onChange((value) => {
            this.Value = value;
          })

        Text(this.Text)
          .id("label")
          .fontColor('#666666')
          .fontSize(this.FontSize)
          .position({
            x: this.Position_x,
            y: this.Position_y
          })
          .animation({
            duration: 300,
            curve: Curve.Friction,
            playMode: PlayMode.Normal
          })
      }
      .width("100%")
      .height(80)
      .backgroundColor(Color.White)
    }
  }
}

导入自定义组件

对PlanB无法处理事件的解决方法包括以下,但没能成功,若有大佬知道怎样正确使用,不胜感激

  1. 使用’@ohos.events.emitter’
  2. 在自定义组件中声明onclick等函数
import {ExInput, rxInput, rxLabel} from './main/widgets/ExInput'
import { TestInput } from './main/widgets/TestInput'

@Entry
@Component
struct Index {
  @State message: string = 'Login'
  username_label = new rxLabel('Username',25,20,40,30,40,5)
  username_input = new rxInput(InputType.Normal,'#666666','#6b9d68',this.username_label)
  pwd_label = new rxLabel('Password',25,20,40,30,40,5)
  pwd_input = new rxInput(InputType.Password,'#666666','#6b9d68',this.pwd_label)
  @State fz : number =25
  @State bc : string = '#666666'
  @State px : number = 40
  @State py : number = 30

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        ExInput({rx_input:this.username_input})
        ExInput({rx_input:this.pwd_input})

        TestInput({
          Type: InputType.Normal,
          Text: 'Username',
          FontSize: this.fz,
          BottomColor: this.bc,
          Position_x: this.px,
          Position_y: this.py
        })
          .animation({
            duration: 300,
            curve: Curve.Friction,
            playMode: PlayMode.Normal
          })
          .onClick(() => {
            console.warn("test1")
            this.fz = 20
            this.bc = '#6b9d68'
            this.px = 40
            this.py = 5
          })
          .onFocus(() => {
            console.warn("test2")
            this.fz = 20
            this.bc = '#6b9d68'
            this.px = 40
            this.py = 5
          })
          .onBlur(()=>{
            this.fz = 25
            this.bc = '#666666'
            this.px = 40
            this.py = 30
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}


  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值