美文网首页
Flutter wechat我的、通讯录页面

Flutter wechat我的、通讯录页面

作者: 老黑来袭 | 来源:发表于2021-01-07 11:58 被阅读0次

下面是我的页面的源代码,代码很简单不进行详述了。

import 'package:flutter/material.dart';
import 'package:wechat_demo/pages/discover/discover_cell.dart';

class MinePage extends StatefulWidget {
  String name = '周佳兴';
  String weChatNum = '微信号: 天青色无敌';
  @override
  _MinePageState createState() => _MinePageState();
}

class _MinePageState extends State<MinePage> {
  Widget headWidget() {
    return Container(
      color: Colors.white,
      height: 200,
      child: Container(
        // color: Colors.yellow,
        margin: EdgeInsets.only(top: 100, bottom: 20),
        padding: EdgeInsets.all(10),
        child: Container(
          // color: Colors.blue,
          child: Row(
            children: [
              Container(
                width: 50, height: 50,
                margin: EdgeInsets.only(left: 20),
                padding: EdgeInsets.all(5),
                // child: Image(
                //   image: AssetImage('images/截屏2021-01-05 下午7.12.15.png'),
                // ), // 图片不能设置圆角
                // 设置圆角
                decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(10),
                    image: DecorationImage(
                        image: AssetImage('images/截屏2021-01-05 下午7.12.15.png'),
                        fit: BoxFit.fill)), // 设置填充模式
              ),
              Container(
                // color: Colors.red,
                margin: EdgeInsets.only(left: 10, right: 5),
                width: MediaQuery.of(context).size.width - 115,
                child: Column(
                  textBaseline: TextBaseline.alphabetic,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Container(
                      // margin: EdgeInsets.only(left: 10),
                      child: Text(
                        widget.name,
                        style: TextStyle(
                          fontSize: 25,
                          color: Colors.black,
                        ),
                      ),
                    ),
                    Container(
                      child: Row(
                        children: [
                          Text(
                            widget.weChatNum,
                            style: TextStyle(
                              fontSize: 14,
                              color: Colors.grey,
                            ),
                          ),
                          Image(
                            image: AssetImage('images/icon_right.png'),
                            width: 15,
                          ),
                        ],
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      ),
                    )
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          Container(
              color: Color.fromRGBO(220, 220, 220, 1),
              child: MediaQuery.removePadding(
                // 去掉默认的刘海
                removeTop: true,
                context: context,
                child: ListView(
                  children: [
                    headWidget(),
                    SizedBox(
                      height: 10,
                    ),
                    DiscoverCell(
                      imageName: 'images/微信 支付.png',
                      title: '支付',
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    DiscoverCell(
                      imageName: 'images/微信收藏.png',
                      title: '收藏',
                    ),
                    Row(
                      children: [
                        Container(
                          width: 50,
                          height: 0.5,
                          color: Colors.white,
                        ),
                      ],
                    ),
                    DiscoverCell(
                      imageName: 'images/微信相册.png',
                      title: '朋友圈',
                    ),
                    Row(
                      children: [
                        Container(
                          width: 50,
                          height: 0.5,
                          color: Colors.white,
                        ),
                      ],
                    ),
                    DiscoverCell(
                      imageName: 'images/微信卡包.png',
                      title: '卡包',
                    ),
                    Row(
                      children: [
                        Container(
                          width: 50,
                          height: 0.5,
                          color: Colors.white,
                        ),
                      ],
                    ),
                    DiscoverCell(
                      imageName: 'images/微信表情.png',
                      title: '表情',
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    DiscoverCell(
                      imageName: 'images/微信设置.png',
                      title: '设置',
                    ),
                  ],
                ),
              )), // 列表
          Container(
            margin: EdgeInsets.only(right: 10, top: 40),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                Image(image: AssetImage('images/相机.png')),
              ],
            ),
            color: Color.fromRGBO(0, 0, 0, 0),
            height: 25,
          ), // 相机
        ],
      ),
    );
  }
}

下面是通讯里页面源码

先说一下通讯录页面简单思路:
通讯录页面有导航、列表、索引条,我的思路为:导航包裹一个Stack小部件,Stack 部件包裹 ListView和索引条部件。

Scaffold(
AppBar:
body: Stack (
children:[
ListView.builder(), 
Container()]
)
)

下面是主页面

import 'package:flutter/material.dart';
import 'package:wechat_demo/const.dart';
import 'package:wechat_demo/pages/discover/discover_child_page.dart';
import 'package:wechat_demo/pages/friends/friend_bar.dart';
import 'package:wechat_demo/pages/pages.friends/friends_data.dart';

class FriendPage extends StatefulWidget {
  @override
  _FriendPageState createState() => _FriendPageState();
}

class _FriendPageState extends State<FriendPage> {
  // 字典放 item 和高度的对应数据
  final Map groupOffSetMap = {
    // INDEX_WORDS[0]: 0.0,
    // INDEX_WORDS[1]: 0.0,
  };

  ScrollController scrollerController;

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

  List<Friends> newDatas = [];
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    newDatas.addAll(datas);
    newDatas.addAll(datas);

    newDatas..addAll(datas);
    newDatas.sort((Friends a, Friends b) {
      return a.indexLetter.compareTo(b.indexLetter);
    });

    var groupOffset = 54.5 * 4;
    for (var item in newDatas) {
      int index = newDatas.indexOf(item);

      if (index < 1 && groupOffSetMap[item.indexLetter] == null) {
        groupOffSetMap.addAll({item.indexLetter: groupOffset});
        groupOffset += 84.5;
      } else if (groupOffSetMap[item.indexLetter] != null) {
        groupOffset += 54.5;
      } else if (groupOffSetMap[item.indexLetter] == null) {
        groupOffSetMap.addAll({item.indexLetter: groupOffset});
        groupOffset += 84.5;
      }
    }
    scrollerController = ScrollController();
  }

  @override
  Widget build(BuildContext context) {
    Widget _itemForRow(BuildContext context, int index) {
      if (index < _headerData.length) {
        return _FriendCell(
          imageAssets: _headerData[index].imageUrl,
          name: _headerData[index].name,
        );
      }
      bool hideIndexLetter = index - 5 >= 0 &&
          newDatas[index - 4].indexLetter == newDatas[index - 5].indexLetter;

      return _FriendCell(
        imageUrl: newDatas[index - 4].imageUrl,
        name: newDatas[index - 4].name,
        groupTitle: hideIndexLetter ? null : newDatas[index - 4].indexLetter,
      );
    }

    return Scaffold(
        appBar: AppBar(
          backgroundColor: weChatThemColor,
          title: Text(
            '通讯录',
            style: TextStyle(color: Colors.black),
          ),
          actions: [
            GestureDetector(
              onTap: () {
                Navigator.of(context).push(MaterialPageRoute(
                  builder: (context) => DiscoverChildPage(
                    title: '添加朋友',
                  ),
                ));
              },
              child: Container(
                margin: EdgeInsets.only(right: 10),
                child: Image(
                  image: AssetImage('images/icon_friends_add.png'),
                  width: 25,
                ),
              ),
            )
          ],
        ),
        body: Stack(
          children: [
            ListView.builder(
              controller: scrollerController, // 控制滚动的
              itemCount: _headerData.length + newDatas.length,
              itemBuilder: _itemForRow,
            ),
            FriendBar(
              friendBarCallBack: (str) {
                if (groupOffSetMap[str] == null) {
                  return;
                }
                ;
                scrollerController.animateTo(groupOffSetMap[str],
                    duration: Duration(microseconds: 100),
                    curve: Curves.easeIn);
              },
            ),
          ],
        ));
  }
}

class _FriendCell extends StatelessWidget {
  final String imageUrl;
  final String name;
  final String groupTitle;
  final String imageAssets;

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

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Container(
          alignment: Alignment.centerLeft,
          padding: EdgeInsets.only(left: 10),
          height: groupTitle != null ? 30 : 0,
          color: Color.fromRGBO(1, 1, 1, 0),
          child: groupTitle != null
              ? Text(
                  groupTitle,
                  style: TextStyle(color: Colors.grey),
                )
              : null,
        ),
        Container(
          color: Colors.white,
          child: Row(
            children: [
              Container(
                  margin: EdgeInsets.all(10),
                  width: 34,
                  height: 34,
                  decoration: BoxDecoration(
                      image: DecorationImage(
                          image: imageUrl != null
                              ? NetworkImage(imageUrl)
                              : AssetImage(imageAssets)),
                      borderRadius: BorderRadius.circular(6))),
              Container(
                child: Text(
                  name,
                  style: TextStyle(fontSize: 17),
                ),
              ),
            ],
          ),
        ),
        Container(
          height: 0.5,
          color: weChatThemColor,
          margin: EdgeInsets.only(left: 50),
        )
      ],
    );
  }
}


下面是自定义搜索条

import 'package:flutter/material.dart';
import 'package:wechat_demo/const.dart';

class FriendBar extends StatefulWidget {
  final void Function(String str) friendBarCallBack;

  FriendBar({this.friendBarCallBack});
  @override
  _FriendBarState createState() => _FriendBarState();
}

class _FriendBarState extends State<FriendBar> {
  Color bColor = Color.fromRGBO(1, 1, 1, 0);
  Color textColor = Colors.black;
  double indicatorY = 0;
  String indictorText = 'A';
  bool indocatorHidden = true;

  int getIndex(BuildContext context, Offset globalPosition) {
    // 坐标转换
    RenderBox box = context.findRenderObject();
    // 转换为当前视图的位置,  details.globalPosition 是相对于全屏幕的
    double y = box.globalToLocal(globalPosition).dy;

    var itemHeight = ScreenHeight(context) / 2 / INDEX_WORDS.length;

    int index = (y ~/ itemHeight).clamp(0, INDEX_WORDS.length - 1);
    return index;
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> words = [];

    for (var item in INDEX_WORDS) {
      words.add(Expanded(
          child: Text(
        item,
        style: TextStyle(fontSize: 10, color: textColor),
      )));
    }

    return Container(
      child: Positioned(
        child: Row(
          children: [
            Container(
              alignment: Alignment(0, indicatorY),
              width: 100,
              child: Stack(
                alignment: Alignment(-0.2, 0),
                children: indocatorHidden
                    ? []
                    : [
                        Image(
                          image: AssetImage('images/气泡.png'),
                          width: 60,
                        ),
                        Text(indictorText),
                      ],
              ),
            ),
            GestureDetector(
              onVerticalDragUpdate: (details) {
                setState(() {
                  int index = getIndex(context, details.globalPosition);
                  widget.friendBarCallBack(INDEX_WORDS[index]);
                  indocatorHidden = false;
                  indictorText =
                      INDEX_WORDS[getIndex(context, details.globalPosition)];
                  indicatorY =
                      2.2 / 26 * getIndex(context, details.globalPosition) -
                          1.1;
                });
              },
              onVerticalDragDown: (details) {
                setState(() {
                  bColor = Color.fromRGBO(1, 1, 1, 0.5);
                  textColor = Colors.white;
                  indocatorHidden = false;
                  indictorText =
                      INDEX_WORDS[getIndex(context, details.globalPosition)];
                  indicatorY =
                      2.2 / 26 * getIndex(context, details.globalPosition) -
                          1.1;
                });
              },
              onVerticalDragEnd: (details) {
                setState(() {
                  bColor = Color.fromRGBO(1, 1, 1, 0);
                  textColor = Colors.black;
                  indocatorHidden = true;
                });
              },
              child: Container(
                width: 20,
                color: bColor,
                child: Column(
                  children: words,
                ),
              ),
            ),
          ],
        ),
        right: 0,
        bottom: ScreenHeight(context) / 8,
        height: ScreenHeight(context) / 2,
        width: 120,
      ),
    );
  }
}

const INDEX_WORDS = [
  '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'
];

相关文章

网友评论

      本文标题:Flutter wechat我的、通讯录页面

      本文链接:https://www.haomeiwen.com/subject/vqlooktx.html