首页 > 其他分享 >ArkUI实现微信主页布局

ArkUI实现微信主页布局

时间:2024-01-08 18:05:12浏览次数:35  
标签:主页 item media app height width 微信 ArkUI icon

一、Tabs实现页面切换

项目整体效果如下:

ArkUI实现微信主页布局_ico

修改Index.ets,实现选项卡切换页面,内容如下:

import { NoteBookComponent } from '../components/NoteBookComponent'
import { FoundComponent } from '../components/FoundComponent'
import { MeComponent } from '../components/MeComponent'
import { WeChatComponent } from '../components/WeChatComponent'

@Entry
@Component
struct Index {
  //初始化值,作为页面索引使用
  @State currentIndex:number = 0
  private tabsController:TabsController = new TabsController()

  //自定义组件,设置tabs显示效果
  @Builder BottomBar(title:string, targetIndex:number, normalImg:Resource, selectedImg:Resource){
    Column(){
      Image(this.currentIndex == targetIndex? selectedImg:normalImg)
        .width(28)
        .height(28)

      Text(title)
        .padding({top:3})
        .fontColor(this.currentIndex == targetIndex ? "#00EE76" : "#6b6b6b")

    }.onClick(()=>{ //点击整个列出现变化
      this.currentIndex = targetIndex
      /**
       * 用来调用TabsController实例的changeIndex方法,目的是更新选项卡的索引。
       * 在这段代码中,this.controller是一个TabsController实例,通过调用changeIndex方法并传入this.index作为参数,
       * 可以实现在用户点击选项卡时更新选项卡的索引位置,从而实现选项卡内容的切换。
       */
      this.tabsController.changeIndex(this.currentIndex)  // 调用控制器的changeIndex方法,更新选项卡的索引
    })
  }
  build() {
    Column(){
      Tabs({
        barPosition:BarPosition.End, //设置Tabs的页签位置。默认值:BarPosition.Start
        controller:this.tabsController,//设置Tabs控制器。
        index:this.currentIndex} //设置初始页签索引。默认值:0
      ){
        TabContent(){
          //页面组件
          WeChatComponent()
        }.tabBar(this.BottomBar("微信",0,$r("app.media.icon_wechat_normal"),$r("app.media.icon_wechat_selected")))

        TabContent(){
          //页面组件
          NoteBookComponent()
        }.tabBar(this.BottomBar("通讯录",1,$r("app.media.icon_book_normal"),$r("app.media.icon_book_selected"),))

        TabContent(){
          //页面组件
          FoundComponent()
        }.tabBar(this.BottomBar("发现",2,$r("app.media.icon_found_normal"),$r("app.media.icon_found_selected")))

        TabContent(){
          //页面组件
          MeComponent()
        }.tabBar(this.BottomBar("我",3,$r("app.media.icon_me_normal"),$r("app.media.icon_me_selected")))
      }
      .vertical(false) //vertical:设置 Tab 是否为左右排列,默认为 false ,表示上下排列
    }
    .width("100%")
    .height('100%')
  }
}

二、实现微信消息页面

微信联系人消息页面分析,剖析如下:

ArkUI实现微信主页布局_ico_02

2.1.实现头部组件

头部组件构成如下:

ArkUI实现微信主页布局_ico_03

在components包下创建HeadComponent.ets,在里面定义组件,后期其他页面也是需要使用,代码如下:

@Component
export struct HeadComponent {
  img:Resource //图标
  textInfo:string//文字说明

  build() {
    Row(){
      Row(){
        //文字
        Text(this.textInfo)
          .fontSize(25)
          .fontWeight(FontWeight.Bold)
      }
      .width("90%")
      .justifyContent(FlexAlign.Center)


      Row(){
        //添加按钮
        Image(this.img)
          .size({width:20, height:20})
      }
      .width("10%")
    }
    .size({width:"100%"})
    .padding({top:15, bottom:15})
  }
}

2.2.实现搜索组件

搜索组件构成如下:

ArkUI实现微信主页布局_Image_04

在components包下创建SearchComponent.ets,在里面定义组件,后期其他页面也是需要使用,代码如下:

@Component
export struct SearchComponent {
  //图标
  img:Resource
  //文字
  textInfo:string

  build() {
    Row(){
      //图标设置样式大小
      Image(this.img)
        .width(25)
        .height(25)
        .margin({right:15})

      Text(this.textInfo)
    }
    .justifyContent(FlexAlign.Center)
    .borderRadius(10)
    .backgroundColor(Color.White)
    .width("90%")
    .height(30)
  }
}

2.3.准备用户或者群聊数据

在ets目录创建子包model包。新建FInderData.ets,内容如下:

//好友类
export class Friends{
  avatar: Resource|Resource[]
  nickName:string
  chatInfo:string

  constructor(avatar:Resource|Resource[],nickName:string, chatInfo:string) {
    this.avatar = avatar
    this.nickName = nickName
    this.chatInfo = chatInfo
  }
}

//准备数据
export let iconList1:Friends[] = [
  new Friends([
  $r("app.media.icon_head01"),
  $r("app.media.icon_head02"),
  $r("app.media.icon_head03"),
  $r("app.media.icon_head04"),
  $r("app.media.icon_head05"),
  $r("app.media.icon_head06"),
  $r("app.media.icon_head07"),
  $r("app.media.icon_head08"),
  $r("app.media.icon_head09"),
  ],"鸿蒙开发交流群","今天学习鸿蒙开发,你来不来!!!"),
  new Friends($r("app.media.icon_head01"),"小兔兔","今天学习鸿蒙开发,你来不来!!!"),
  new Friends($r("app.media.icon_head02"),"低沉旳呢喃","一怒之下将朋友删除"),
  new Friends($r("app.media.icon_head03"),"果子小公公","今天学习鸿蒙开发,你来不来!!!"),
  new Friends($r("app.media.icon_head04"),"传说里的你","This is the setting of textOverflow to Clip text content This is the setting of textOverflow to None text content. This is the setting of textOverflow to Clip text content This is the setting of textOverflow to None text content."),
  new Friends($r("app.media.icon_head05"),"张三你好","旧的不去新的不来,人这一生分离太多"),
  new Friends($r("app.media.icon_head06"),"桃洛憬","快乐活着,一切皆有可能,新年快乐!"),
  new Friends($r("app.media.icon_head07"),"一追再追","但有可能会因为连败影响到球员的心态和情绪"),
  new Friends([
  $r("app.media.icon_head11"),
  $r("app.media.icon_head12"),
  $r("app.media.icon_head13"),
  $r("app.media.icon_head14"),
  $r("app.media.icon_head15"),
  $r("app.media.icon_head16"),
  $r("app.media.icon_head17"),
  $r("app.media.icon_head18"),
  $r("app.media.icon_head19"),
  ],"致一科技项目群","今天下午项目评审,请各位按时参加"),
  new Friends($r("app.media.icon_head08"),"清梦一场","1-2输球的结果,也是国足时隔39年再一次输给中国香港队,"),
  new Friends($r("app.media.icon_head09"),"紫涩微凉","在昨晚进行的封闭热身赛中,国足1-2不敌中国香港队"),
  new Friends($r("app.media.icon_head10"),"哥帅但不是蟋蟀","在纳兹莫加医院,口腔科医生盛磊给患者看病。"),
  new Friends($r("app.media.icon_head11"),"诗酒乔木","微信删除的聊天记录怎么恢复?"),
  new Friends($r("app.media.icon_head12"),"空白的昵称","今天学习鸿蒙开发,你来不来!!!"),
  new Friends($r("app.media.icon_head13"),"快乐的天使","一怒之下将朋友删除"),
  new Friends($r("app.media.icon_head14"),"流行的趋势","今天学习鸿蒙开发,你来不来!!!"),
  new Friends($r("app.media.icon_head15"),"萌萌哒","新年快乐!花样倒计时伴随0点钟响全国各地喜迎2024"),
  new Friends($r("app.media.icon_head16"),"勇往直前","旧的不去新的不来,人这一生分离太多"),
  new Friends($r("app.media.icon_head17"),"唯美主义","快乐活着,一切皆有可能,新年快乐!"),
  new Friends($r("app.media.icon_head18"),"战斗的勇气","一怒之下将朋友删除"),
  new Friends($r("app.media.icon_head19"),"瞳孔中的我","今天学习鸿蒙开发,你来不来!!!"),
  new Friends($r("app.media.icon_head20"),"贰玥眼号","新年快乐!花样倒计时伴随0点钟响全国各地喜迎2024"),
  new Friends($r("app.media.icon_head21"),"寒冷渗进的温暖","旧的不去新的不来,人这一生分离太多"),
  new Friends($r("app.media.icon_head22"),"桃洛憬","快乐活着,一切皆有可能,新年快乐!"),
  new Friends($r("app.media.icon_head23"),"甜甜圈小贩","快乐活着,一切皆有可能,新年快乐!")
]

2.4.实现用户或者群组件

实现用户或者群组件,拆解构成如下:

ArkUI实现微信主页布局_ico_05

在WeChat目录下创建WeChatItem.ets,实现组件,如下:

import { Friends } from '../../model/FInderData'
@Component
export struct WeChatItem {
  friend:Friends
  build() {
    //信息列表
    Row(){
      //如果avatar是一个数组,则表示是群聊
      if (Array.isArray(this.friend.avatar)){
        //如果是数组,则是群聊头像,采用网格布局
        Grid(){
          ForEach(this.friend.avatar, (img, index)=>{
            GridItem(){
              Image(img) //网格布局群聊头像
            }
          })
        }
        .width(50)
        .height(50)
        .margin({left:30, right:10})
        .align(Alignment.Start) //Alignment.Start起始端纵向居中。设置元素内容在元素绘制区域内的对齐方式。默认值:Alignment.Center横向和纵向居中。
        .rowsTemplate("1fr 1fr 1fr") //三行
        .columnsTemplate("1fr 1fr 1fr")//三列布局
        .borderRadius(4) //全局半径
      }else {
        //如果是单个图片,则是个人好友
        Image(this.friend.avatar) //头像
          .width(50)
          .height(50)
          .margin({left:30,right:10})
          .borderRadius(4)
      }

      Column(){
        Text(this.friend.nickName).fontColor("#1C1C1C").fontSize(18) //昵称
        //聊天记录
        Text(this.friend.chatInfo)
          .fontColor("#B4CDCD")
          .maxLines(1) //和textOverflow配合使用,超过一行则截断,
          .textOverflow({overflow:TextOverflow.Ellipsis}) //超过一行显示显示省略号
      }
      .alignItems(HorizontalAlign.Start)
      .width(240)

    }
    .width("100%")
    .height(60)
    .backgroundColor("#F5FFFA")
  }
}

2.5.实现用户或者群聊天组件列表

实现用户或者群组件,拆解构成如下:

ArkUI实现微信主页布局_ico_06

在WeChat目录下创建WeChatListItem.ets,实现聊天组件,如下:

import { Friends, iconList1 } from '../../model/FInderData'
import { WeChatItem } from './WeChatItem'

@Component
export struct WeChatListItem {
  build() {
    List({space:2}){
      //循环产生用户列表
      ForEach(iconList1, (item:Friends, index)=>{
        ListItem(){
          //信息列表
          /*Row(){
            //如果avatar是一个数组,则表示是群聊
            if (Array.isArray(item.avatar)){
              //如果是数组,则是群聊头像,采用网格布局
              Grid(){
                ForEach(item.avatar, (img, index)=>{
                  GridItem(){
                    Image(img) //网格布局群聊头像
                  }
                })
              }
              .width(50)
              .height(50)
              .margin({left:30, right:10})
              .align(Alignment.Start) //Alignment.Start起始端纵向居中。设置元素内容在元素绘制区域内的对齐方式。默认值:Alignment.Center横向和纵向居中。
              .rowsTemplate("1fr 1fr 1fr") //三行
              .columnsTemplate("1fr 1fr 1fr")//三列布局
              .borderRadius(4) //全局半径
            }else {
              //如果是单个图片,则是个人好友
              Image(item.avatar) //头像
                .width(50)
                .height(50)
                .margin({left:30,right:10})
                .borderRadius(4)
            }

            Column(){
              Text(item.nickName).fontColor("#1C1C1C").fontSize(18) //昵称
              //聊天记录
              Text(item.chatInfo)
                .fontColor("#B4CDCD")
                .maxLines(1) //和textOverflow配合使用,超过一行则截断,
                .textOverflow({overflow:TextOverflow.Ellipsis}) //超过一行显示显示省略号
            }
            .alignItems(HorizontalAlign.Start)
            .width(240)

          }
          .width("100%")
          .height(60)
          .backgroundColor("#F5FFFA")*/
          WeChatItem({friend:item})
        }
      })
    }
    .height("100%")
    .width("100%")
  }
}

2.6.创建主页

在components包下创建 WeChatComponent.ets,由上面定义的子组件构成整个聊天信息页面,分别由:

  • 头部组件
  • 搜索框
  • 电脑登陆提示
  • 好友和群聊列表

内容如下:

import { HeadComponent } from './HeadComponent'
import { LoginPromptComponent } from './WeChat/LoginPromptComponent'
import { SearchComponent } from './SearchComponent'
import { WeChatItem } from './WeChat/WeChatItem'

@Component
export struct WeChatComponent {

  build() {
    Column(){
      //首行
      HeadComponent({textInfo:"微信", img:$r("app.media.icon_add")})
      //搜索框
      SearchComponent({img:$r("app.media.icon_search"), textInfo:"搜索"})
      //电脑登陆提示信息
      LoginPromptComponent()
      //好友和群聊列表
      WeChatItem()
  }
    .size({width:"100%", height:"100%"})
    .backgroundColor("#F5F5F5")
}
}

2.7.预览

在这里代码创建完成后在主页Index.ets下调用WeChatComponent ,然后预览如下:

ArkUI实现微信主页布局_Text_07

三、实现通讯录页面

页面分解图如下:

ArkUI实现微信主页布局_Image_08

3.1.准备数据

在model包下创建NoteBookData.ets文件,用于准备后面的数据,内容如下:

export interface INoteBookItem{
  icon:Resource
  title:string
  bgColor: string
}
//准备数据
export let NoteBookDataList:INoteBookItem[] = [
  {
    icon:$r("app.media.icon_new_friends"),
    title:"新的朋友",
    bgColor:"#9FB6CD"
  },

  {
    icon:$r("app.media.icon_public_account"),
    title:"仅聊天的朋友",
    bgColor:"#9FB6CD"
  },

  {
    icon:$r("app.media.icon_group_chat"),
    title:"群聊",
    bgColor:"#9FB6CD"
  },

  {
    icon:$r("app.media.icon_tag"),
    title:"标签",
    bgColor:"#9FB6CD"
  }
]

3.2.定义布局方式

页面布局分析拆解如下:

ArkUI实现微信主页布局_Image_09

这里是对新的朋友、仅聊天的朋友、群聊和标签进行布局,在 components包下创建子包NoteBook,然后创建 NoteBookListComponent.ets,循内容如下:

import { INoteBookItem, NoteBookDataList } from '../../model/NoteBookData'

@Component
export struct NoteBookListComponent {
  build() {
    Column(){
      List({space:10}){
        ForEach(NoteBookDataList,(item:INoteBookItem, index)=>{
          ListItem(){
            //循环产生新朋友、群聊、仅聊天
            Row(){
              //加载图片
              Image(item.icon).width(25).height(25)
              //文字描述
              Text(item.title)
                .fontSize(20)
                .margin({left:10})
            }
            .padding({left:20})
            .width("95%")
            .justifyContent(FlexAlign.Start)
            .backgroundColor(Color.White)
          }
        })
      }.divider({ strokeWidth: 1, color: "#F5F5F5" }) //分割线
    }
    .width("100%")
    .height("100%")
    .alignItems(HorizontalAlign.Center) //水平居中
    .justifyContent(FlexAlign.Center) //垂直居中
    .backgroundColor("#F5F5F5") //整个列表背景颜色
  }
}

3.3.创建通讯录页面

根据上面定义的组件内容,在components包下创建通讯录页面NoteBookComponent.ets,如下

import { HeadComponent } from './HeadComponent'
import { NoteBookListComponent } from './NoteBook/NoteBookListComponent';
import { SearchComponent } from './SearchComponent'

//定义字母数字
let uppercaseLetters: string[] = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];

//定义接口
interface PersonInterface{
  name:string
}

//定义按照首字母分组,一个组A下有多个用户
interface ContractPersonInterface{
  char:string,
  personItem:PersonInterface[] //一个字母开头会有多个用户
}

@Component
export struct NoteBookComponent {
  //准备用户列表
  @State personList: ContractPersonInterface[] = [
    {char:"A", personItem:[{"name":"阿大"},{"name":"阿二"},{"name":"阿三"},{"name":"奥特曼"},{"name":"奥特蛋"},{"name":"阿二"},{"name":"阿三"},{"name":"奥特曼"},]},
    {char:"B", personItem:[{"name":"宝贝"},{"name":"宝宝"},{"name":"宝儿"},{"name":"宝贝儿"},{"name":"宝贝宝贝"},{"name":"宝宝"},{"name":"宝儿"},{"name":"宝贝儿"},{"name":"宝贝宝贝"}]},
    {char:"C", personItem:[{"name":"草莓"},{"name":"菜菜"},{"name":"小菜"},{"name":"小仓"},{"name":"小虫"},{"name":"菜菜"},{"name":"小菜"},]}
  ]

  //定义一个状态selectedIndex,初始值为0,表示选中的索引。
  @State selectedIndex:number = 0

  //创建一个Scroller实例,用于滚动列表。
  scroller:Scroller = new Scroller()

  //定义一个名为GroupHeader的构建器函数,接受一个字符串参数word,返回一个组件。用于显示字母A、B、C这些组
  @Builder GroupHeader(word:string){
    Row(){
      Text(word)
        .fontSize(18)
        .width("100%")
        .padding(5)
        .margin({left:10})
    }
  }

  build() {
    Column(){
      //头信息
      HeadComponent({textInfo:"通讯录",img:$r("app.media.icon_add")})


      //剩余的内容放在一起, 主要是拼音列表要堆叠在用户列表上面
      Stack({alignContent:Alignment.End}){//alignContent:Alignment.End设置字母表,在右侧显示
        List(){
          ListItem(){
            Column(){
              //搜索框
              SearchComponent({img:$r("app.media.icon_search"), textInfo:"搜索"}).margin({top:10, bottom:10})

              //仅聊天的朋友、新的朋友、标签、公众号
              NoteBookListComponent()
                .height(180)
                .padding({left:10,top:14,right:10,bottom:14})
                .backgroundColor(Color.White)

              //好友列表
              List({scroller:this.scroller}){
                //循环显示用户信息
                ForEach(this.personList,(wordItem:ContractPersonInterface, index)=>{
                  ListItemGroup({
                    header:this.GroupHeader(wordItem.char) //显示组名字母,例如A
                  }){
                    ForEach(wordItem.personItem, (p:PersonInterface, index2)=>{ //显示A组对应的用户
                      ListItem(){//循环取出组中的信息
                        Row(){
                          //显示用户昵称
                          Text(p.name).fontSize(16).width("100%")
                        }
                        .margin({top:20})
                      }
                    })
                  }
                  .padding({left:25, top:20, right:25})
                  .divider({ strokeWidth: 1, color: "#F0FFF0" }) //分割线
                } )
              }
              .backgroundColor(Color.White)
              .sticky(StickyStyle.Header) //设置ListItemGroup中header和footer是否要吸顶或吸底。
              .onScrollIndex((index:number)=>{//列表滑动时触发。计算索引值时,ListItemGroup作为一个整体占一个索引值,不计算ListItemGroup内部ListItem的索引值。
                this.scroller.scrollToIndex(index) //滑动到指定Index。
                this.selectedIndex = index //滑动后修改索引值,以此来控制下面的字母改变
                console.info(`本次列表选中的索引为:${index}`)
              })

            }
          }
        }

        //可以与容器组件联动用于按逻辑结构快速定位容器显示区域的组件。 uppercaseLetters 字母索引字符串 selected:0默认初始化值
        AlphabetIndexer({arrayValue:uppercaseLetters, selected:0})
          .selected(this.selectedIndex) //设置选中项索引值。
          .onSelect((index)=>{  //索引条选中回调,返回值为当前选中索引。
            this.selectedIndex = index
            this.scroller.scrollToIndex(index)
          })
      }
      .height("100%")


    }
    .size({width:"100%", height:"100%"})
    .backgroundColor("#F5F5F5")
  }
}

3.4.测试

在Index.ets中添加上面的通讯录组件,然后进行测试,效果如下:

ArkUI实现微信主页布局_Text_10

四、发现页面

页面拆解图如下:

ArkUI实现微信主页布局_ico_11

4.1.准备数据

在model包下的,InfoData.ets下准备数据内容如下:

export interface InfoDataItem{
  icon:Resource
  title:string
  headIcon?:Resource
  desc?:string
  isRadPoint?:Boolean //小红点
}

export let InfoDataList:InfoDataItem[] = [
  {
    icon:$r("app.media.icon_friends"),
    title:"朋友圈",
    headIcon:$r("app.media.icon_friend_head"),
    desc:"",
    isRadPoint:true
  },
  {
    icon:$r("app.media.icon_video_number"),
    title:"视频号",
    headIcon:$r("app.media.icon_video_head"),
    desc:"卓伟又爆了大瓜了",
    isRadPoint:true
  },

  {
    icon:$r("app.media.icon_live_broadcast"),
    title:"直播",
    headIcon:$r("app.media.icon_broadcast_head"),
    desc:"50个朋友关注",
    isRadPoint:true
  },
  {
    icon:$r("app.media.icon_sweep"),
    title:"扫一扫"
  },
  {
    icon:$r("app.media.icon_shake"),
    title:"摇一摇"
  },
  {
    icon:$r("app.media.icon_see"),
    title:"看一看",
    headIcon:$r("app.media.icon_see_head"),
    desc:"2个朋友在看",
    isRadPoint:true
  },
  {
    icon:$r("app.media.icon_search_finder"),
    title:"搜一搜"
  },
  {
    icon:$r("app.media.icon_nearby"),
    title:"附近"
  },
  {
    icon:$r("app.media.icon_shop"),
    title:"购物"
  },

  {
    icon:$r("app.media.icon_game"),
    title:"游戏",
    headIcon:$r("app.media.icon_game_head"),
    desc:"朋友刚刚发布动态",
    isRadPoint:true
  },

  {
    icon:$r("app.media.icon_applet"),
    title:"小程序"
  },
]

4.2.创建组件1

朋友圈、扫一扫、摇一摇、搜一搜、附近、购物、小程序这几个功能页面布局分析如下:

ArkUI实现微信主页布局_Image_12

然后在components包下创建Finder子包,然后新建FinderItem01.ets,实现组件,代码内容如下:

@Component
export struct FinderItem01 {
  //朋友圈、扫一扫、摇一摇、搜一搜、附近、购物、小程序
  icon:Resource       //图标
  title:string        //名称
  headIcon?:Resource  //用户头像
  desc?:string        //描述
  isRadPoint?:Boolean //是否小红点

  build() {
    Column(){
      Row(){
        //头像和分类名称
        Row(){
          //图片
          Image(this.icon).width(28).height(28).margin({right:12})
          //文字
          Text(this.title)
        }.margin({left:30, top:10})

        //右侧 图标 小红点 >
        Row(){
          //这里是为朋友圈分类准备的,如果有为ture,会在右侧显示小红点和用户头像
          if(this.isRadPoint){
            //实现红点
            Badge({
              value:"",//没有内容就是一个红点
              position: BadgePosition.RightTop, //在右上角显示
              style:{badgeSize:6,badgeColor:Color.Red} //样式:大小、颜色
            }){
              Image(this.headIcon)
                .borderRadius(10)
                .width(28)
                .height(28)
                .margin({right:12})
            }
          }
          //尖括号
          Image($r("app.media.icon_right_angle_bracket"))
            .margin({right:28})
            .width(28)
            .height(28)
          
        }
      }
      .justifyContent(FlexAlign.SpaceBetween)
      .width("100%")
      .height(48)
    }
    .width("100%")
    .height("100%")
  }
}

4.3.创建组件2

视频号功能页面布局分析如下:

ArkUI实现微信主页布局_Image_13

然后在components的Finder子包下创建FinderItem02.ets,实现组件,代码内容如下:

@Component
export struct FinderItem02 {
  //视频号
  icon:Resource
  title:string
  headIcon?:Resource
  desc?:string
  isRadPoint?:Boolean //小红点

  build() {
    Column(){
      Row(){
        Row(){
          //图片
          Image(this.icon).width(28).height(28).margin({right:12})
          //文字
          Text(this.title)
        }.margin({left:30, top:10})

        //右侧 图标 小红点 >
        Row(){
          if(this.isRadPoint){
            //实现红点
            Badge({
              value:"",//没有内容就是一个红点
              position: BadgePosition.RightTop, //在右上角显示
              style:{badgeSize:6,badgeColor:Color.Red} //样式:大小、颜色
            }){
              Image(this.headIcon)
                .borderRadius(10)
                .width(28)
                .height(28)
                .margin({right:12})
            }
          }else {
            //只显示图片
            Image(this.headIcon)
              .borderRadius(10)
              .width(28)
              .height(28)
              .margin({right:12})
          }
          Text(this.desc).lineHeight(28).margin({right:12})
          Image($r("app.media.icon_right_angle_bracket")).margin({right:28}).width(28).height(28)
        }
      }.justifyContent(FlexAlign.SpaceBetween)
      .width("100%")
      .height(48)
    }
    .width("100%")
    .height("100%")
  }
}

4.4.创建组件3

直播、看一看、游戏功能页面布局分析如下:

ArkUI实现微信主页布局_ico_14

然后在components的Finder子包下创建FinderItem03.ets,实现组件,代码内容如下:

@Component
export struct FinderItem03 {
  //直播、看一看、游戏
  icon:Resource
  title:string
  headIcon?:Resource
  desc?:string
  isRadPoint?:Boolean //小红点

  build() {
    Column(){
      Row(){
        Row(){
          //图片
          Image(this.icon).width(28).height(28).margin({right:12})
          //文字
          Text(this.title)
        }.margin({left:30, top:10})

        //右侧 图标 小红点 >
        Row(){
          Text(this.desc).lineHeight(28).margin({right:12})

          if(this.isRadPoint){
            //实现红点
            Badge({
              value:"",//没有内容就是一个红点
              position: BadgePosition.RightTop, //在右上角显示
              style:{badgeSize:6,badgeColor:Color.Red} //样式:大小、颜色
            }){
              Image(this.headIcon)
                .borderRadius(10)
                .width(28)
                .height(28)
                .margin({right:12})
            }
          }else {
            //只显示图片
            Image(this.headIcon)
              .borderRadius(10)
              .width(28)
              .height(28)
              .margin({right:12})
          }
          Image($r("app.media.icon_right_angle_bracket")).margin({right:28}).width(28).height(28)
        }
      }.justifyContent(FlexAlign.SpaceBetween)
      .width("100%")
      .height(48)
    }
    .width("100%")
    .height("100%")
  }
}

4.5.创建发现页面

在components下创建发现页面FoundComponent.ets,代码如下:

import { InfoDataItem, InfoDataList } from '../model/InfoData'
import { FinderItem01 } from './Finder/FinderItem01'
import { FinderItem02 } from './Finder/FinderItem02'
import { FinderItem03 } from './Finder/FinderItem03'
import { HeadComponent } from './HeadComponent'
import { SearchComponent } from './SearchComponent'
@Component
export struct FoundComponent {
  build() {
    Column(){
      Row(){
        Text("发现").fontSize(25).fontWeight(FontWeight.Bold)
      }
      .justifyContent(FlexAlign.Center)
      .width("100%")
      .height(65)
      .backgroundColor("#EDEDED")


      List(){
        ForEach(InfoDataList, (item:InfoDataItem, key)=>{
          /**
           * 这里根据key不同,决定之前定义的那个样式
           */
          //朋友圈、扫一扫、摇一摇、附近 购物、小程序
          if(key==0||key==3||key==4||key==6||key==7||key==8||key==10){
            //而下面在再次判断,目的是为了让他们能有不用的样式,出现间隔
            if(key==0){
              ListItem(){
                FinderItem01({
                  icon:item.icon,
                  title:item.title,
                  headIcon:item.headIcon,
                  desc:item.desc,
                  isRadPoint:item.isRadPoint
                })
                  .backgroundColor(Color.White)
                  .height(48)
                  .margin({bottom:16})
              }
            }
            else if(key==3){
              ListItem(){
                FinderItem01({icon:item.icon,
                  title:item.title,
                  headIcon:item.headIcon,
                  desc:item.desc,
                  isRadPoint:item.isRadPoint
                })
                  .backgroundColor(Color.White)
                  //和上面的区别只是样式的不同
                  .height(48)
                  .margin({top:20})
              }
            }else if(key==7){
              ListItem(){
                FinderItem01({icon:item.icon,
                  title:item.title,
                  headIcon:item.headIcon,
                  desc:item.desc,
                  isRadPoint:item.isRadPoint
                })
                  .backgroundColor(Color.White)
                    //和上面的区别只是样式的不同
                  .height(48)
                  .margin({top:20,bottom:20})
              }
            }else if(key==10){
              ListItem(){
                FinderItem01({icon:item.icon,
                  title:item.title,
                  headIcon:item.headIcon,
                  desc:item.desc,
                  isRadPoint:item.isRadPoint
                })
                  .backgroundColor(Color.White)
                    //和上面的区别只是样式的不同
                  .height(48)
                  .margin({top:20})
              }
            }
            else {
              ListItem(){
                FinderItem01({icon:item.icon,
                  title:item.title,
                  headIcon:item.headIcon,
                  desc:item.desc,
                  isRadPoint:item.isRadPoint
                })
                  .backgroundColor(Color.White)
                    //和上面的区别只是样式的不同
                  .height(48)
              }
            }
          }

          //视频号
          if(key==1){
            ListItem(){
              FinderItem02({
                icon:item.icon,
                title:item.title,
                headIcon:item.headIcon,
                desc:item.desc,
                isRadPoint:item.isRadPoint
              })
                .backgroundColor(Color.White)
                .height(48)
            }
          }

          //直播、看一看、游戏
          if(key==2||key==5||key==9){
            if(key==5){
              ListItem(){
                FinderItem03({
                  icon:item.icon,
                  title:item.title,
                  headIcon:item.headIcon,
                  desc:item.desc,
                  isRadPoint:item.isRadPoint
                })
                  .backgroundColor(Color.White)
                  .height(48)
                  .margin({top:20})
              }
            }else {
              ListItem(){
                FinderItem03({
                  icon:item.icon,
                  title:item.title,
                  headIcon:item.headIcon,
                  desc:item.desc,
                  isRadPoint:item.isRadPoint
                })
                  .backgroundColor(Color.White)
                  .height(48)
              }
            }
          }
        })
      }
    }
    .width("100%")
    .height("100%")
    .backgroundColor("#F5F5F5")
  }
}

4.6.测试

在Index.ets中调用FoundComponent.ets中定义的组件,预览如下:

ArkUI实现微信主页布局_Image_15

五、实现-我页面

对于页面布局进行拆解,如下图:

ArkUI实现微信主页布局_Text_16

5.1.实现个人信息

在components目录下创建子包Me,然后创建UserInfoComponent.ets,代码如下:

@Component
export struct UserInfoComponent {
  build() {
    Row(){
      //整个分为两列

      //1.头像
      Column(){
        Image($r("app.media.icon_head23")).width(90).height(90).borderRadius(10).margin({right:12})
      }.layoutWeight(1) //权重1,占主轴剩余空间1/3,父容器尺寸确定时,设置了layoutWeight的子元素在主轴布局尺寸按照权重进行分配,忽略本身尺寸设置。
      Column(){
        //昵称
        Row(){
          Text("站在街角等雨淋").fontSize(22).fontWeight(FontWeight.Bold)
        }.width("100%")

        Row(){
          //微信号
          Text("微信号: Tenderness").margin({right:20})
          //二维码
          Image($r("app.media.icon_qrcode")).width(18).height(18).margin({right:20})
          //右尖括号
          Image($r("app.media.icon_right_angle_bracket")).width(12).height(12).margin({left:20})
        }.width("100%").margin({top:4})

        //状态
        Row(){
          //  border width:边框宽度;color:边框颜色;radius:边框半径;
          Text(" + 状态").fontSize(10).border({width:1, color:"#DDDDDD",radius:10}).margin({right:10})

          //堆叠三个图标
          Stack({alignContent:Alignment.BottomEnd}){
            Image($r("app.media.icon_001")).width(10).height(10).borderRadius(5)

            Image($r("app.media.icon_002")).width(10).height(10).borderRadius(5).margin({left:10,right:10})

            Image($r("app.media.icon_003")).width(10).height(10).borderRadius(5).margin({left:20,right:20})
          }
          Text("等20个朋友").fontSize(12).margin({left:10})
        }.margin({top:4})
      }
      .alignItems(HorizontalAlign.Start) //水平向左排列
      .justifyContent(FlexAlign.Center)  //垂直方法居中排列
      .layoutWeight(3) // 权重3,占主轴剩余空间3/4
      .margin({top:20, left:30})
    }
    .height(120)
    .width("100%")
    .margin({left:20, top:30})
  }
}

5.2.实现单个行组件

实现组件原型如下:

ArkUI实现微信主页布局_Text_17

在包Me,然后创建MeInfoComponent.ets,代码如下:

@Component
export struct MeInfoComponent {
  img:Resource           //图标
  title:string           //文字描述

  build() {
    Row(){
      Row(){
        //图标
        Image(this.img).width(28).height(28)

        //名称,例如:服务、朋友圈
        Text(this.title)
          .margin({left:12, right:130})
          .textAlign(TextAlign.Center)
          .height(28)
      }
      .width("80%")

      //右尖括号
      Image($r("app.media.icon_right_angle_bracket")).width(24).height(24)

    }
    .height(56)
    .width("100%")
    .justifyContent(FlexAlign.SpaceEvenly)
  }
}

5.3.准备组件列表数据

在model包下创建MeData.ets,准备组件列表数据如下:

export interface MeDataInterface{
  icon:Resource
  title:string
}

//定义数据
export let MeDataList:MeDataInterface[] = [
  {icon:$r("app.media.icon_collect"), title:"朋友圈"},
  {icon:$r("app.media.icon_wechat_moment"), title:"视频号"},
  {icon:$r("app.media.icon_card_bag"), title:"卡包"},
  {icon:$r("app.media.icon_emote"), title:"表情"}
]

5.4.实现组件列表

实现组件原型如下:

ArkUI实现微信主页布局_ico_18

Me包下创建MeInfoListComponent.ets,通过List组件然后循环产生组件列表,代码如下:

import { MeDataInterface, MeDataList } from '../../model/MeData'
import { MeInfoComponent } from './MeInfoComponent'

@Component
export struct MeInfoListComponent {

  build() {
    Column(){
      List(){
        ForEach(MeDataList, (item:MeDataInterface, index)=>{
          ListItem(){
            //循环出现行,各个组件
            MeInfoComponent({img:item.icon, title:item.title})
          }
        })
      }.divider({ strokeWidth: 1, color: "#F5F5F5" }) //分割线
    }
    .width("100%")
    .height("100%")
  }
}

5.5.编写页面-我

利用上面创建的组件,在components包创建MeComponent.ets,如下:

import { MeInfoComponent } from './Me/MeInfoComponent'
import { MeInfoListComponent } from './Me/MeInfoListComponent'
import { UserInfoComponent } from './Me/UserInfoComponent'
@Component
export struct MeComponent {
  build() {
    Column(){
      Row(){
        //用户信息
        UserInfoComponent()
      }.width("100%")

      //单个组件
      Row(){
        MeInfoComponent({img:$r("app.media.icon_service"), title:"服务"})
      }
      .alignItems(VerticalAlign.Center) //垂直居中
      .height(48)
      .margin({top:20})
      .backgroundColor(Color.White)

      //多个组件列表
      Row(){
        MeInfoListComponent()
      }.height(220)
      .margin({top:20, bottom:20})
      .backgroundColor(Color.White)
    
      //单个组件
      Row(){
        MeInfoComponent({img:$r("app.media.icon_setting"), title:"设置"})
      }
      .alignItems(VerticalAlign.Center) //垂直居中
      .height(48)
      .margin({top:20})
      .backgroundColor(Color.White)


    }
    .width("100%")
    .height("100%")
    .backgroundColor("#F5F5F5")
  }
}

5.6.测试

在Index.ets中调用MeComponent.ets中定义的组件,预览效果如下:

ArkUI实现微信主页布局_ico_19


标签:主页,item,media,app,height,width,微信,ArkUI,icon
From: https://blog.51cto.com/u_13661275/9148126

相关文章

  • pytest-yaml 测试平台-4.生成allure报告,报告反馈企业微信、钉钉、飞书通知
    前言定时任务执行完成后生成可视化allure报告,并把结果发到企业微信,钉钉,飞书通知群里。生成allure报告添加定时任务执行完成后生成allure报告查看报告详情报告会显示详细的request和response详细信息也可以查看log日志报告反馈-企业微信创建定时任务时添加企业微信token企业微信t......
  • 苹果IOS如何支持微信小程序分享
    各位同学们好!我是咕噜铁蛋!,我们经常需要与读者分享有关移动应用的使用方法和技巧。微信小程序是一种便捷的应用形式,可以在微信内部直接使用,而无需下载和安装。本文铁蛋讲详细介绍iOS苹果支持微信小程序类型分享的使用方法,帮助你更好地了解和利用这一功能,拓展你的内容传播渠道。一.什......
  • 在微信中接入gemini
    ......
  • 电脑版微信缓存记录找回好友
    工具下载地址下载地址:https://wwot.lanzouw.com/b0395rbcd 密码:3zp8工具说明此工具是通过读取历史缓存数据找回删除的好友,需要你们还是好友的时候,有在这台电脑上登录过,才有可能找回。使用教程电脑上登录微信,打开软件点击一键读取,等显示输出读取完成后,点击读取结果查看是否......
  • 记录Springboot中向企业微信指定人员发送含链接的消息
    背景:从海康智能门禁获取到了进入教室的人脸信息,由此得到一批用户List,等会儿就要实时向这批用户发送消息“***,您已进入**教室,请填写使用情况表<ahref="****">”。  过程:读了微信的开发者文档,摸索着写了测试代码。在debug时,发现微信传来的是{"errcode":60020,"errmsg":"not......
  • Android项目实战(六十八):微信分享的实现
    系统分享://系统转发方式publicstaticvoidshareBySystem(Contextcontext,Filefile){WxUtils.checkFileUriExposure();Intentintent=newIntent(Intent.ACTION_SEND);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);Uricont......
  • Hbuilderx 创建 uni-app 项目,发行微信小程序
    创建uni-app项目,发行微信小程序发行微信小程序时,需要注意主包因uni_modules文件大超包问题。在Hbuilderx创建uni-app项目时,uni_modules文件会包含一些第三方组件和插件,而这些文件可能会导致主包的体积超过小程序的限制。为了解决这个问题,可以采取一些措施来减小主包的体积。一种......
  • 微信小程序直播(二):如何使用第三方直播插件快速实现企业直播间
    ZEGO微信小程序直播SDK可以在微信小程序中提供实时音视频直播服务,从而实现电商直播/在线教育/在线问诊/视频客服等各种业务场景。但是由于微信小程序的官方限制,在某些场景下需要额外使用ZEGO提供的小程序直播插件才能实现实时音视频直播功能。本节将介绍需要使用与不需要使用Z......
  • 做私域是该用企业微信还是个人微信呢?
    还在认为做私域就是加人、拉群和发圈吗?这理解太片面了!腾讯官方解释私域是“维护长远而忠诚的客户关系”,为用户提供价值和有价值的服务,才是私域运营的核心。......
  • 在微信小程序中如何改变默认打开的页面
    各位伙伴们新年好,我是咕噜铁蛋!我们经常需要在微信小程序中定制化我们的应用程序,包括改变默认打开的页面。今天铁蛋也收集了些内容,详细介绍在微信小程序中如何改变默认打开的页面,帮助你实现更好的用户体验和个性化的应用程序。一.我们先了解微信小程序的默认打开页面在微信小程序中,默......