鸿蒙next list组件多布局实现 IM 聊天

915 阅读2分钟

前言导读

image.png

image.png

image.png

具体实现

  • 数据模型

export  class UserInfo{
  msg:string='';
  type:number=0;
  constructor(msg: string, type: number) {
    this.msg = msg;
    this.type = type;
  }

}
  • list 布局

我们通过userinfo里面的 userinfo.type 来判断是显示左边布局还是显示右边布局UI

List(){

  ForEach(this.datalist,(userinfo:UserInfo, index:number)=>{
    if(userinfo.type==CommonConstant.RECEIVED){
      ListItem(){
        this.leftview(userinfo)
      }
    }else if(userinfo.type==CommonConstant.SENT){
      ListItem(){
        this.rightview(userinfo)
      }
    }
  })

}.height('90%')
.width('100%')
  • 底部输入框

我们再发送按钮点击事件里面根据this.flag 值来给我们userinfo 里面的消息类型type设置不同的消息类型

Row(){
 Row(){
   TextInput({placeholder:'请输入消息'})
     .maxLength(12)
     .type(InputType.Number)
     .inputStyle()
     .onChange((value:string)=>{
       this.message=value;
     }).margin({left:10})

   Button('发送',{type:ButtonType.Capsule})
     .width(100)
     .height(45)
     .fontSize(16)
     .fontWeight(FontWeight.Medium)
     .backgroundColor($r('app.color.login_button_color'))
     .margin({left:10})
     .onClick(()=>{
       if(!this.flag){
         this.login(this.message,1)
         this.flag=true;
       }else{
         this.login(this.message,2)
         this.flag=false;
       }
     })

 }.justifyContent(FlexAlign.Start)
 .width('100%')
 .margin({top:8})
}.height(50).width('100%').align(Alignment.BottomEnd)
  • 左边消息布局

@Builder
private  leftview(userinfo:UserInfo){
 Row(){

   Text(userinfo.msg).fontSize(15)
     .fontColor(Color.White).backgroundColor(Color.Green).align(Alignment.Start).height(40)
   Blank()
 }.height(40).margin({top:15,left:5})
}
  • 右边消息布局
@Builder
private  rightview(userinfo:UserInfo){
  RelativeContainer(){
    Row(){
      Blank()
      Text(userinfo.msg).fontSize(15)
        .fontColor(Color.White).align(Alignment.End).backgroundColor(Color.Red).height(40)
    }.height(40).margin({top:15}).justifyContent(FlexAlign.SpaceEvenly).alignRules(AlignRue)

  }.height(40).margin({top:15,right:5}).width('100%')

}
  • 初始化默认数据

@State message: string = '';
@State datalist:Array<UserInfo>=[]
@State flag:boolean=false;


aboutToAppear() {
this.datalist.push(new UserInfo("我是徐老师",1))
 this.datalist.push(new UserInfo("你好我是陈浩南",2))
 this.datalist.push(new UserInfo("鸿蒙好学吗",1))
 this.datalist.push(new UserInfo("鸿蒙上手很快的",2))
 this.datalist.push(new UserInfo("鸿蒙未来如何",1))
 this.datalist.push(new UserInfo("未来可期",2))

}

完整代码

import { UserInfo } from './UserInfo';
import CommonConstant  from  '../common/CommonConstants';



@Extend(TextInput) function  inputStyle(){
  .placeholderColor($r('app.color.placeholder_color'))
  .height(45)
  .fontSize(18)
  .backgroundColor($r('app.color.background'))
  .width('70%')
  .margin({top:0})
}

//黑色字体样式
@Extend(Text) function  blackTextStyle(){
  .fontColor($r('app.color.black_text_color'))
  .fontSize(18)
  .fontWeight(FontWeight.Medium)
}

let AlignRue:Record<string,Record<string,string|VerticalAlign|HorizontalAlign>> = {
  'top': { 'anchor': '__container__', 'align': VerticalAlign.Top },
  'right': { 'anchor': '__container__', 'align': HorizontalAlign.End }
}

@Entry
@Component
struct Index {
  @State message: string = '';
  @State datalist:Array<UserInfo>=[]
  @State flag:boolean=false;


  aboutToAppear() {
   this.datalist.push(new UserInfo("我是徐老师",1))
    this.datalist.push(new UserInfo("你好我是陈浩南",2))
    this.datalist.push(new UserInfo("鸿蒙好学吗",1))
    this.datalist.push(new UserInfo("鸿蒙上手很快的",2))
    this.datalist.push(new UserInfo("鸿蒙未来如何",1))
    this.datalist.push(new UserInfo("未来可期",2))

  }


  build() {
      Column(){
        List(){

          ForEach(this.datalist,(userinfo:UserInfo, index:number)=>{
            if(userinfo.type==CommonConstant.RECEIVED){
              ListItem(){
                this.leftview(userinfo)
              }
            }else if(userinfo.type==CommonConstant.SENT){
              ListItem(){
                this.rightview(userinfo)
              }
            }
          })

        }.height('90%')
        .width('100%')
        Row(){
          Row(){
            TextInput({placeholder:'请输入消息'})
              .maxLength(12)
              .type(InputType.Number)
              .inputStyle()
              .onChange((value:string)=>{
                this.message=value;
              }).margin({left:10})

            Button('发送',{type:ButtonType.Capsule})
              .width(100)
              .height(45)
              .fontSize(16)
              .fontWeight(FontWeight.Medium)
              .backgroundColor($r('app.color.login_button_color'))
              .margin({left:10})
              .onClick(()=>{
                if(!this.flag){
                  this.login(this.message,1)
                  this.flag=true;
                }else{
                  this.login(this.message,2)
                  this.flag=false;
                }
              })

          }.justifyContent(FlexAlign.Start)
          .width('100%')
          .margin({top:8})
        }.height(50).width('100%').align(Alignment.BottomEnd)
      } .height('100%')
      .width('100%')
  }

    login(getmessage:string,gettype:number){
    let userinfo:UserInfo=new UserInfo(getmessage,gettype);
    this.datalist.push(userinfo);
  }
   @Builder
   private  leftview(userinfo:UserInfo){
    Row(){

      Text(userinfo.msg).fontSize(15)
        .fontColor(Color.White).backgroundColor(Color.Green).align(Alignment.Start).height(40)
      Blank()
    }.height(40).margin({top:15,left:5})
   }
  @Builder
  private  rightview(userinfo:UserInfo){
    RelativeContainer(){
      Row(){
        Blank()
        Text(userinfo.msg).fontSize(15)
          .fontColor(Color.White).align(Alignment.End).backgroundColor(Color.Red).height(40)
      }.height(40).margin({top:15}).justifyContent(FlexAlign.SpaceEvenly).alignRules(AlignRue)

    }.height(40).margin({top:15,right:5}).width('100%')

  }
}

最后总结;

鸿蒙next 里面的list组件里面listitem 也是支持多布局的 我们只需要在ForEach 的时候拿到index 下标或者是是我们自己的设置的条件来渲染不同的item 布局即可 这样我们就可以实现我们实战开发工程的列表中复杂的布局效果 更新相关的知识可以关注我的课程

都在我的实战课程里面。各位同学如果想学习更多的知识可以关注我的B站课程

课程地址

www.bilibili.com/cheese/play…

项目内容:

  • 1 常用布局组件的学习

  • 2 网络请求工具类封装

  • 3 arkui 生命周期启动流程

  • 4 日志工具类的封装

  • 5 自定义组合组件的封装

  • 6 路由导航跳转的使用

  • 7 本地地数据的缓存 以及缓存工具类的封装

  • 8 欢迎页面的实现

  • 9 登录案例和自动登录效果实现

  • 10 请求网络数据分页上拉加载 下拉刷新的实现

  • 11 list数据懒加载实现

  • 12 webview组件的使用