美文网首页python
微信项目 - 发现页面与我的页面

微信项目 - 发现页面与我的页面

作者: 浅墨入画 | 来源:发表于2021-11-21 23:00 被阅读0次

    上面文章我们初步进行了项目搭建,下面就来开发微信项目的发现页面

    自定义cell

    通过微信发现页面的UI图,我们知道Cell需要对外提供四个属性titlesubTitleimageNamesubImageName用于页面展示

    • 新建自定义Cell文件,名称为discover_cell.dart
    import 'package:flutter/material.dart';
    
    class DiscoverCell extends StatelessWidget {
      final String title;
      final String subTitle;
      final String imageName;
      final String subImageName;
    
      DiscoverCell({
        // @required表示必须要有title imageName值
        @required this.title,
        this.subTitle,
        @required this.imageName,
        this.subImageName
        // 添加assert断言,进行提示
      }) : assert(title != null, 'title 不能为空'), assert(imageName != null, 'imageName 不能为空');
    
      @override
      Widget build(BuildContext context) {
        return Container(
            // Cell添加背景色
            color: Colors.white,
            height: 55,
            child: Row(
              // 主轴是spaceBetween
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                //left
                Container(
                  padding: EdgeInsets.all(10),
                  child: Row(
                    children: [
                      Image(
                        image: AssetImage(imageName),
                        width: 20,
                      ),
                      SizedBox(
                        width: 15,
                      ),
                      Text(title),
                    ],
                  ),
                ),
    
                //right
                Container(
                  padding: EdgeInsets.all(10),
                  child: Row(
                    children: [
                      subTitle != null ? Text(subTitle) : Text(''),
                      subImageName != null
                          ? Image(
                              image: AssetImage(subImageName),
                              width: 12,
                            )
                          : Container(),
                      Image( //右侧箭头
                        image: AssetImage('images/icon_right.png'),
                        width: 15,
                      )
                    ],
                  ),
                ),
              ],
            ),
          );
      }
    }
    

    发现页面完善

    discover_page.dart文件添加ListView

    import 'package:flutter/material.dart';
    import 'discover_cell.dart';
    
    class DiscoverPage extends StatefulWidget {
      @override
      _DiscoverPageState createState() => _DiscoverPageState();
    }
    
    class _DiscoverPageState extends State<DiscoverPage> {
      Color _themeColor = Color.fromRGBO(220, 220, 220, 1.0);
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              backgroundColor: _themeColor,
              //以下三个是专门为了安卓使用的属性,title用于安卓退出后台顶部显示app名称
              centerTitle: true,
              title: Text('发现'),
              elevation: 0.0, //设置NaviBar底部边栏为隐藏
            ),
            body: Container(
              color: _themeColor,
              height: 800,
              child: ListView(
                children: <Widget>[
                  DiscoverCell(
                    imageName: 'images/朋友圈.png',
                    title: '朋友圈',
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  DiscoverCell(
                    imageName: 'images/扫一扫2.png',
                    title: '扫一扫',
                  ),
                  // cell分隔线
                  Row(
                    children: <Widget>[
                      Container(width: 50, height: 0.5, color: Colors.white),
                      Container(height: 0.5, color: Colors.grey)
                    ],
                  ),
                  DiscoverCell(
                    imageName: 'images/摇一摇.png',
                    title: '摇一摇',
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  DiscoverCell(
                    imageName: 'images/看一看icon.png',
                    title: '看一看',
                  ),
                  Row(
                    children: <Widget>[
                      Container(width: 50, height: 0.5, color: Colors.white),
                      Container(height: 0.5, color: Colors.grey)
                    ],
                  ),
                  DiscoverCell(
                    imageName: 'images/搜一搜 2.png',
                    title: '搜一搜',
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  DiscoverCell(
                    imageName: 'images/附近的人icon.png',
                    title: '附近的人',
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  DiscoverCell(
                    imageName: 'images/购物.png',
                    title: '购物',
                    subTitle: '618限时特价',
                    subImageName: 'images/badge.png',
                  ),
                  Row(
                    children: <Widget>[
                      Container(width: 50, height: 0.5, color: Colors.white),
                      Container(height: 0.5, color: Colors.grey)
                    ],
                  ),
                  DiscoverCell(
                    imageName: 'images/游戏.png',
                    title: '游戏',
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  DiscoverCell(
                    imageName: 'images/小程序.png',
                    title: '小程序',
                  ),
                ],
              ),
            ));
      }
    }
    
    运行效果

    cell点击切换页面

    上面我们实现了发现页面的列表,但是Cell还无法点击,下面实现Cell点击以及跳转逻辑

    • cell添加手势GestureDetector,添加完手势点击cell就会有回调事件onTap
    // discover_cell.dart文件中添加手势
    @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () {
            print('haha _$title');
          },
          child: Container(
            // Cell添加背景色
            color: Colors.white,
            height: 54,
    ......
    
    • 新建二级页面discover_child_page.dart,用于cell跳转
    import 'package:flutter/material.dart';
    
    class DiscoverChildPage extends StatelessWidget {
      final String title;
      DiscoverChildPage({this.title});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('$title'),
          ),
          body: Center(
            child: Text('$title'),
          ),
        );
      }
    }
    
    • GestureDetector回调方法onTap中添加跳转逻辑
    // 导入头文件
    import 'discover_child_page.dart';
    
    @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () {
            // 添加跳转二级页面方法
            Navigator.of(context).push(
              // BuildContext上下文
              MaterialPageRoute(builder: (BuildContext context) =>
                DiscoverChildPage(title: '$title')
              )
            );
          },
          child: Container(
            // Cell添加背景色
            color: Colors.white,
            height: 54,
    ......
    
    点击跳转二级页面

    注意⚠️:如果不小心点到Pub get导致flutter卡住,一般是网络的原因,也有可能是不小心改动了pubspec.yaml文件,复制一份重新配置。

    有状态的cell

    Widget与界面的关系
    • Widget是界面的描述,并不是界面。
    • 如果cell内容非常复杂,出于性能考虑,需要把cell部分改成有状态的
    • 如果cell整体是有状态的,界面的描述会被整体改变
    • 如果cell整体是有状态的,渲染的时候并不是整体渲染,而是整个cellWidget会重新创建。为了提高性能,可以把cell的部分Widget抽取出来做成可变的,而整个cell是不可变的。
    • 如果整个cell是不可变的,在创建对象的时候,cell不会重新创建,而是cell内部的Widget会重新创建,也就是Container会重新创建。

    GestureDetector手势的点击状态

    @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () {
            print('haha _$title');
            Navigator.of(context).push(
                MaterialPageRoute(builder: (BuildContext context) =>
                    DiscoverChildPage(title: '$title')
                )
            );
          },
          // 点击
          onTapDown: (TapDownDetails details) {
            print('点下来了!');
          },
          // 取消点击
          onTapCancel: () {
            print('离开了!');
          },
    ......
    
    // 控制台成功打印
    flutter: 点下来了!
    flutter: 离开了!
    flutter: 点下来了!
    flutter: haha _DiscoverCell.title
    
    • 修改DiscoverCell为有状态的
    import 'package:flutter/material.dart';
    
    import 'discover_child_page.dart';
    
    class DiscoverCell extends StatefulWidget {
      final String title;
      final String subTitle;
      final String imageName;
      final String subImageName;
    
      DiscoverCell({
        // @required表示必须要有title imageName值
        required this.title,
        this.subTitle,
        required this.imageName,
        this.subImageName
        // 添加assert断言,进行提示
      }) : assert(title != null, 'title 不能为空'), assert(imageName != null, 'imageName 不能为空');
    
      // 有状态的Widget需要实现createState方法
      @override
      State<StatefulWidget> createState() => _DiscoverCellState();
    }
    
    // 问题一 _DiscoverCellState访问不到DiscoverCell中的 title等属性?
    // 解决方法  使用 widget.title, _DiscoverCellState中使用widget,这里的widget就是DiscoverCell
    
    class _DiscoverCellState extends State<DiscoverCell> {
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () {
            print('haha _$widget.title');
            Navigator.of(context).push(
                MaterialPageRoute(builder: (BuildContext context) =>
                    DiscoverChildPage(title: widget.title)
                )
            );
          },
          onTapDown: (TapDownDetails details) {
            print('点下来了!');
          },
          onTapCancel: () {
            print('离开了!');
          },
          child: Container(
            // Cell添加背景色
            color: Colors.white,
            height: 54,
            child: Row(
              // 主轴是spaceBetween
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                //left
                Container(
                  padding: EdgeInsets.all(10),
                  child: Row(
                    children: [
                      Image(
                        image: AssetImage(widget.imageName),
                        width: 20,
                      ),
                      SizedBox(
                        width: 15,
                      ),
                      Text(widget.title),
                    ],
                  ),
                ),
    
                //right
                Container(
                  padding: EdgeInsets.all(10),
                  child: Row(
                    children: [
                      widget.subTitle != null ? Text(widget.subTitle) : Text(''),
                      widget.subImageName != null
                          ? Image(
                        image: AssetImage(widget.subImageName),
                        width: 12,
                      )
                          : Container(),
                      Image( //右侧箭头
                        image: AssetImage('images/icon_right.png'),
                        width: 15,
                      )
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    

    问题: _DiscoverCellState访问不到DiscoverCell中的 title等属性?
    解决方法:_DiscoverCellState中使用widget.title来访问DiscoverCell中的title属性,这里的widget就是DiscoverCell

    • color抽取出来,通过手势点击修改cell背景色
    class _DiscoverCellState extends State<DiscoverCell> {
      Color _currentColor = Colors.white;
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () {
            print('haha _$widget.title');
            Navigator.of(context).push(
                MaterialPageRoute(builder: (BuildContext context) =>
                    DiscoverChildPage(title: widget.title)
                )
            );
            setState(() {
              _currentColor = Colors.white;
            });
          },
          onTapDown: (TapDownDetails details) {
            print('点下来了!');
            setState(() {
              _currentColor = Colors.grey;
            });
          },
          onTapCancel: () {
            print('离开了!');
            setState(() {
              _currentColor = Colors.white;
            });
          },
          child: Container(
            // Cell添加背景色
            color: _currentColor,
            height: 54,
    ......
    
    点击Cell时灰色,取消点击变成白色

    我的页面布局

    新建discover文件夹右击 -> new -> package,把发现相关页面放入

    • mine_page.dart文件中编写内容
    • MediaQuery.removePadding内属性removeTop: true,可以去掉刘海屏顶部的默认偏移
    import 'package:flutter/material.dart';
    import 'discover/discover_cell.dart';
    
    class MinePage extends StatefulWidget {
      @override
      _MinePageState createState() => _MinePageState();
    }
    
    class _MinePageState extends State<MinePage> {
    
      Widget headerWidget() {
        return Container(
          height: 200,
          color: Colors.red,
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Container(
            color: Color.fromRGBO(220, 220, 220, 1),
            child: Stack(
              children: [
                //列表,用Container包一层会更灵活一点,方便抽出来
                Container(
                  //Flutter官方封装的一些属性!!
                  child: MediaQuery.removePadding(
                      // 去掉刘海屏顶部的偏移部分
                      removeTop: true,
                      context: context,
                      child: ListView(
                        children: [
                          //头部
                          headerWidget(),
                          //list
                          SizedBox(
                            height: 10,
                          ),
                          DiscoverCell(
                            imageName: 'images/微信 支付.png',
                            title: '支付',
                          ),
                          SizedBox(
                            height: 10,
                          ),
                          DiscoverCell(
                            imageName: 'images/微信收藏.png',
                            title: '收藏',
                          ),
                          Row(
                            children: <Widget>[
                              Container(
                                  width: 50, height: 0.5, color: Colors.white),
                              Container(height: 0.5, color: Colors.grey)
                            ],
                          ), //分割线
                          DiscoverCell(
                            imageName: 'images/微信相册.png',
                            title: '相册',
                          ),
                          Row(
                            children: <Widget>[
                              Container(
                                  width: 50, height: 0.5, color: Colors.white),
                              Container(height: 0.5, color: Colors.grey)
                            ],
                          ), //分割线
                          DiscoverCell(
                            imageName: 'images/微信卡包.png',
                            title: '卡包',
                          ),
                          Row(
                            children: <Widget>[
                              Container(
                                  width: 50, height: 0.5, color: Colors.white),
                              Container(height: 0.5, color: Colors.grey)
                            ],
                          ), //分割线
                          DiscoverCell(
                            imageName: 'images/微信表情.png',
                            title: '表情',
                          ),
                          SizedBox(
                            height: 10,
                          ),
                          DiscoverCell(
                            imageName: 'images/微信设置.png',
                            title: '设置',
                          ),
                        ],
                      )
                  ),
                ),
                //相机 --也可以尝试用Positioned实现
                Container(
                  // 可以专门抽出一个文件配置这些 颜色 margin 等变量,color: Colors.red, Top Margin 40
                  margin: EdgeInsets.only(top: 40, right: 15),
                  height: 25,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.end, //主轴方向在右侧
                    children: [
                      Image(image: AssetImage('images/相机.png')),
                    ],
                  ),
                ),
              ],//
            ),
          ),
        );
      }
    }
    
    运行效果

    我的页面头部

    我的页面头部,自定义小部件headerWidget开发

    • 获取屏幕宽度MediaQuery.of(context).size.width
    Widget headerWidget() {
        return Container(
          height: 200,
          color: Colors.white,
          child: Container(
            child: Container(
              margin: EdgeInsets.only(top: 100, bottom: 20, left: 20, right: 10),
              // color: Colors.red,
              child: Row(
                children: [
                  //头像
                  Container(
                    width: 70,
                    height: 70,
                    decoration: BoxDecoration(
                        color: Colors.blue,
                        borderRadius: BorderRadius.circular(12),
                        image: DecorationImage(
                            image: AssetImage('images/Hank.png'),
                            fit: BoxFit.cover)),
                  ),
                  //右边的部分,包一个Expanded,懒得算了。
                  Expanded(
                      child: Container(
                        // color: Colors.red,
                        // margin:
                        //     EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 5),
                        // width: MediaQuery.of(context).size.width - 100,
                        padding: EdgeInsets.only(left: 10, top: 8),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            Container(
                              height: 35,
                              child: Text(
                                'HK',
                                style: TextStyle(fontSize: 25, color: Colors.black),
                              ),
                            ), //昵称
                            Container(
                              height: 35,
                              child: Row(
                                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                children: <Widget>[
                                  Text(
                                    '微信号:12334',
                                    style: TextStyle(fontSize: 17, color: Colors.grey),
                                  ),
                                  Image(
                                    image: AssetImage('images/icon_right.png'),
                                    width: 15,
                                  )
                                ],
                              ),
                            ), //微信号+箭头
                          ],
                        ),
                      )),
                ],
              ),
            ),
          ),
        );
      }
    
    运行效果

    相关文章

      网友评论

        本文标题:微信项目 - 发现页面与我的页面

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