Flutter学习-15- 微信项目学习-通讯录页面

「这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战」。

1. 宏定义

我们在项目中使用一些公共的类比如我们iOS的宏定义,在flutter中也有类似的我们直接创建一个文件,类似我们的iOS中的头文件,之后定义一些常用的类,比如颜色,标题样式等。使用的时候直接option+enter自动导入报错的即可

Color ThemeColor = const Color.fromRGBO(220, 220, 220, 1.0);
TextStyle TitleStyle = const TextStyle(fontSize: 16,fontWeight: FontWeight.bold,color: Colors.black);
复制代码

image.png

2. 导航栏

appBar: AppBar(
    title: const Text('通讯录页面'),
    centerTitle: true,
    elevation: 0.0,
    backgroundColor: ThemeColor,
  actions: [
    GestureDetector(
      onTap: (){
        Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => DiscoverChildPage("添加朋友")));

      },
      child:Container(
        padding: EdgeInsets.only(right: 15),
        child:  Image.asset('images/icon_friends_add.png',width: 30,),
      )
    ),
  ],
  leading: IconButton(onPressed: (){
    Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => DiscoverChildPage("更多")));


  }, icon: Icon(Icons.menu)) ,


),
复制代码

image.png

其中主要介绍下actionsleading

  • actions 是一个数组元素为控件widget

image.png 我们在添加一个

image.png

相当于iOS导航栏中的rightButtonItems我们可以添加多个widege

  • leading

image.png

相当于导航栏左控件返回一个widget

leading:  IconButton(onPressed: (){
  Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => DiscoverChildPage("更多")));


}, icon: Icon(Icons.menu)) ,
复制代码

image.png

添加2个的话需要注意尺寸我这里直接使用了IconButton尺寸不对报错

image.png

3. 数据处理

我们定义数据

class Friends {
  Friends({this.imageUrl, this.name, this.indexLetter, this.imageAssets});
  final String? imageAssets;
  final String? imageUrl;
  final String? name;
  final String? indexLetter;
}

List<Friends> datas = [
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/women/27.jpg',
      name: 'Lina',
      indexLetter: 'L'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/women/17.jpg',
      name: '菲儿',
      indexLetter: 'F'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/women/16.jpg',
      name: '安莉',
      indexLetter: 'A'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/men/31.jpg',
      name: '阿贵',
      indexLetter: 'A'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/women/22.jpg',
      name: '贝拉',
      indexLetter: 'B'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/women/37.jpg',
      name: 'Lina',
      indexLetter: 'L'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/women/18.jpg',
      name: 'Nancy',
      indexLetter: 'N'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/men/47.jpg',
      name: '扣扣',
      indexLetter: 'K'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/men/3.jpg',
      name: 'Jack',
      indexLetter: 'J'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/women/5.jpg',
      name: 'Emma',
      indexLetter: 'E'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/women/24.jpg',
      name: 'Abby',
      indexLetter: 'A'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/men/15.jpg',
      name: 'Betty',
      indexLetter: 'B'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/men/13.jpg',
      name: 'Tony',
      indexLetter: 'T'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/men/26.jpg',
      name: 'Jerry',
      indexLetter: 'J'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/men/36.jpg',
      name: 'Colin',
      indexLetter: 'C'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/women/12.jpg',
      name: 'Haha',
      indexLetter: 'H'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/women/11.jpg',
      name: 'Ketty',
      indexLetter: 'K'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/women/13.jpg',
      name: 'Lina',
      indexLetter: 'L'),
  Friends(
      imageUrl: 'https://randomuser.me/api/portraits/women/23.jpg',
      name: 'Lina',
      indexLetter: 'L'),
];
复制代码

数据包含一个固定的上面4个下面联系人 先定义头的数据

final List<Friends> _headerData = [
  Friends(imageAssets: 'images/新的朋友.png', name: '新的朋友'),
  Friends(imageAssets: 'images/群聊.png', name: '群聊'),
  Friends(imageAssets: 'images/标签.png', name: '标签'),
  Friends(imageAssets: 'images/公众号.png', name: '公众号'),
];
复制代码

4. Cell的创建

cell我们分析下主要是包含一个头像一个标题下划线,和组的头视图

class FriendCell extends StatelessWidget {

  FriendCell({this.imageUrl, this.name, this.groupTitle, this.imageAssets});

  final String? imageUrl;
  final String? name;
  final String? groupTitle;
  final String? imageAssets;

  @override
  Widget build(BuildContext context) {
    return Container(

      child: Column(

        children: [
          //头部,没有标题的话不显示
          Container(
            child: groupTitle !=null ? Text(groupTitle!,style: TextStyle(color: Colors.grey),) : null,
            height: groupTitle != null ?30:0,
            color: ThemeColor,
            alignment: Alignment.centerLeft,
            padding: EdgeInsets.only(left: 15),
          ),
          Container(//cell内容
            child: Row(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                Container(margin: EdgeInsets.all(10),child:imageAssets == null ? Image.network(imageUrl!,width: 34,height: 34,) : Image.asset(imageAssets!),height: 34,width: 34,),//头像
                Container(

                  alignment: Alignment.centerLeft,
                  width: screenWidth(context) -54,
                  child: Column(

                    children: [
                  Container(alignment: Alignment.centerLeft,padding: EdgeInsets.only(left: 15),child: Text(name!,style: TitleStyle,),height: 54,),//姓名
                  Container(color: ThemeColor,height: 0.5,),
                ],),)
              ],
            ),
          )
        ],

      ),

    );
  }
}
复制代码

我们定义下listView,使用ListView.builder的形式处理,类似我们iOS的cell的复用表现形式而不是静态cell

  • itemBuilder

image.png 我们定义下头数组和联系人数组,数据为之前我们定义的

final List<Friends> _headerData = [
  Friends(imageAssets: 'images/新的朋友.png', name: '新的朋友'),
  Friends(imageAssets: 'images/群聊.png', name: '群聊'),
  Friends(imageAssets: 'images/标签.png', name: '标签'),
  Friends(imageAssets: 'images/公众号.png', name: '公众号'),
];
final List<Friends> _listDatas = [];

Widget _itemBuilder(BuildContext context, int index) {
  if (index < _headerData.length) {
    //前4个
   return FriendCell(imageAssets: _headerData[index].imageAssets,
      name: _headerData[index].name,);
  } else {
   return FriendCell(imageAssets: _listDatas[index - _headerData.length].imageAssets,
      name: _listDatas[index - _headerData.length].name,);
  }
}
复制代码

这里进行区分,分为前4个和后面的。在listView展示

child: ListView.builder(itemBuilder: _itemBuilder,
itemCount: _headerData.length+_listDatas.length,
复制代码

效果大致如下 image.png

我们添加一下_listDatas的数据

@override
void initState() {
  // TODO: implement initState
  super.initState();
  _listDatas
  ..addAll(datas)
  ..addAll(datas);
  //排序
  _listDatas.sort((Friends a, Friends b) {
    return a.indexLetter!.compareTo(b.indexLetter!);
  });

}
复制代码

初始化状态的时候我们进行数据的添加和处理,通过数组的sort方法进行排序,比较它们两两的首字母,按顺序进行排序

  • 分组标题

我们的cell只有传入组标题的时候才会进行展示,那么我们只要判断当前数组的元素每一个下一个比较,如果首字母相同就不展示,说明展示过了

bool isHideGroupTitle = (index -_headerData.length>0 &&_listDatas[index-_headerData.length].indexLetter == _listDatas[index-_headerData.length-1].indexLetter);
复制代码

头部的组固定的,当前列表比如第5个数据的时候,index =4 ,则index -_headerData.length>0false。所以展示头

Widget _itemBuilder(BuildContext context, int index) {
  bool isHideGroupTitle = (index -_headerData.length>0 &&_listDatas[index-_headerData.length].indexLetter == _listDatas[index-_headerData.length-1].indexLetter);
  if (index < _headerData.length) {
    //前4个
   return FriendCell(imageAssets: _headerData[index].imageAssets,
      name: _headerData[index].name,);
  } else {

   return FriendCell(
      imageUrl: _listDatas[index - _headerData.length].imageUrl,
      name: _listDatas[index - _headerData.length].name,
      groupTitle: isHideGroupTitle?null: _listDatas[index - _headerData.length ].indexLetter,);
  }
}
复制代码

image.png

image.png

下一篇实现右侧指示条,以及指示条的联动。

猜你喜欢

转载自juejin.im/post/7029992484864262151