8、Flutter - 项目实战 - 仿微信(二)发现页面

Flutter - 项目实战 - 仿微信(二)发现页面

 

接上篇:7、Flutter - 项目实战 - 仿微信(一)BottomNavigationBar 4个主页面显示

详细代码参见Demo

Demo地址 -> wechat_demo

 

其他相关联文章

7、Flutter - 项目实战 - 仿微信(一)BottomNavigationBar 4个主页面显示

8、Flutter - 项目实战 - 仿微信(二)发现页面

9、Flutter - 项目实战 - 仿微信(三)我的页面

10、Flutter - 项目实战 - 仿微信(四)数据准备

11、Flutter - 项目实战 - 仿微信(五)通讯录

12、Flutter - 项目实战 - 仿微信(六)聊天页面

 

效果:


 

创建文件夹discover

把前面创建的  discover_page  放进去。

如上图分析,这种在iOS中做的话应该用一个UITableView来实现,在Flutter 里面有一个列表的显示是ListView,里面可以放我们想要的widget

那就先创建一个cell,将ListView 中的widget 抽出来实现一下

 

1、discover_cell.dart

1.1、代码

标题:title

子标题:subTitle   例如:618这样的活动名

标题前面的图片:imageName

子标题后的图片:subImageName  例如:618后面的红点

最后面的箭头因为都有,就写死了这里,不再用变量

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({
    this.title,
    this.subTitle,
    this.imageName,
    this.subImageName,
  })  : assert(title != null, 'title 不能为空'),
        assert(imageName != null, 'imageName 不能为空');

  @override
  State<StatefulWidget> createState() {
    return _DiscoverCellState();
  }
}

class _DiscoverCellState extends State<DiscoverCell> {
  Color _currentColor = Colors.white;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        //单击
        print('hello');
        Navigator.of(context).push(MaterialPageRoute(
            builder: (BuildContext context) => DiscoverChildPage(
                  title: widget.title,
                ))); //push跳转
        setState(() {
          _currentColor = Colors.white;
        });
      },
      onTapDown: (TapDownDetails details) {
        //手势点击的时候变灰
        setState(() {
          _currentColor = Colors.grey;
        });
      },
      onTapCancel: () {
        //手势离开
        print('离开了!');
        setState(() {
          _currentColor = Colors.white;
        });
      },
      child: Container(
        color: _currentColor,
        height: 54,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween, //左右两边对齐
          children: <Widget>[
            //left
            Container(
              padding: EdgeInsets.all(10),
              child: Row(
                children: <Widget>[
                  Image(
                    image: AssetImage(widget.imageName),
                    width: 20,
                  ),
                  SizedBox(width: 15),
                  Text(widget.title),
                ],
              ),
            ),

            //right
            Container(
              padding: EdgeInsets.all(10),
              child: Row(
                children: <Widget>[
                  widget.subTitle != null ? Text(widget.subTitle) : Text(''),
                  widget.subImageName != null
                      ? Container(
                          child: Image(
                            image: AssetImage(widget.subImageName),
                            width: 15,
                          ),
                          margin: EdgeInsets.only(left: 10, right: 10),
                        )
                      : Container(),
                  Image(
                    image: AssetImage('images/icon_right.png'),
                    width: 15,
                  ),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

1.2、GestureDetector 手势的识别

本质是 StatelessWidget,里面包括了多种手势
class GestureDetector extends StatelessWidget {}

手势的冲突及其他更多可参考: https://www.jianshu.com/p/dc4853c33562

1.2.1、onTap(){}, 点击事件

点击的时候,通过push跳转到对应的页面,这里不做具体的页面了。用一个个统一的页面,动态修改title来实现

页面discover_child_page.dart  代码见2、discover_child_page.dart 

Navigator.of(context).push(MaterialPageRoute(
       builder: (BuildContext context) => DiscoverChildPage(
           title: widget.title,
       ))); //push跳转
    setState(() {
        _currentColor = Colors.white;
});

push到discover_child_page 页面,调用 DiscoverChildPage设置title 为 当前点击的widget.title

然后将cell的背景色修改为白色(_currentColor = Colors.white;)(点击的时候修改为灰色,便于区分点击的cell)

 

1.2.2、onTapDown: (TapDownDetails details) {}  点击点击开始

点击开始的时候修改cell背景色为灰色

1.2.3、onTapCancel: () {}  手势点击离开

手势离开的的时候修改cell背景为白色

 

2、discover_child_page.dart

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'),
      ),
    );
  }
}

这个页面就一个导航栏、title和页面中央显示一下title的内容,所以没什么好说的

 

3、discover_page.dart

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

class DiscoverPage extends StatefulWidget {
  @override
  _ChatPageState createState() => _ChatPageState();
}

class _ChatPageState extends State<DiscoverPage> {
  Color _themeColor = Color.fromRGBO(220, 220, 220, 1.0);
  double _left_distance = 50;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: _themeColor,
        centerTitle: true, //安卓需要
        title: Text('发现'),
        elevation: 0.0, //底部边栏
      ),
      body: Container(
        color: _themeColor,
        height: 800,
        child: ListView(
          children: <Widget>[
            DiscoverCell(
              imageName: 'images/朋友圈.png',
              title: '朋友圈',
            ),
            SizedBox(
              //加一个横向的分割条,设置一个高度
              height: 10,
            ),
            DiscoverCell(
              imageName: 'images/扫一扫.png',
              title: '扫一扫',
            ),
            Row(
              children: <Widget>[
                Container(
                  width: _left_distance,
                  height: 0.5,
                  color: Colors.white,
                ),
                Container(
                  height: 0.5,
                )
              ],
            ),
            DiscoverCell(
              imageName: 'images/摇一摇.png',
              title: '摇一摇',
            ),
            SizedBox(
              height: 10,
            ),
            DiscoverCell(
              imageName: 'images/看一看icon.png',
              title: '看一看',
            ),
            Row(
              children: <Widget>[
                Container(
                  width: _left_distance,
                  height: 0.5,
                  color: Colors.white,
                ),
                Container(
                  height: 0.5,
                )
              ],
            ),
            DiscoverCell(
              imageName: 'images/搜一搜.png',
              title: '搜一搜',
            ),
            SizedBox(
              height: 10,
            ),
            DiscoverCell(
              imageName: 'images/附近的人icon.png',
              title: '附近的人',
            ),
            SizedBox(
              height: 10,
            ),
            DiscoverCell(
              imageName: 'images/购物.png',
              title: '购物',
              subImageName: 'images/badge.png',
              subTitle: '618限时特价',
            ),
            Row(
              children: <Widget>[
                Container(
                  width: _left_distance,
                  height: 0.5,
                  color: Colors.white,
                ),
                Container(
                  height: 0.5,
                )
              ],
            ),
            DiscoverCell(
              imageName: 'images/游戏.png',
              title: '游戏',
            ),
            SizedBox(
              height: 10,
            ),
            DiscoverCell(
              imageName: 'images/小程序.png',
              title: '小程序',
            ),
          ],
        ),
      ),
    );
  }
}

3.1、导航栏

导航栏这里centerTitle 这是安卓中需要配置的,让title居中。

elevation 设置其在图层最上层

 

3.2、body 页面

ListView 类似iOS的tableView,是列表视图

然后顺序的去添加DiscoverCell

在cell之间会有一条分割线,而且这个分割线是从文字开始的。这里用一个横向布局来实现

Row(
  children: <Widget>[
    Container(
      width: _left_distance,
      height: 0.5,
      color: Colors.white,
    ),
    Container(
      height: 0.5,
    )
  ],
),

前面用一个白色的、后面用灰色的,这样做出来的线就是从文字开始的分割线了

宽的分割线是自己而是用

SizedBox(
    height: 10,
),

 

做完之后可以运行看一下。这个页面比较简单,具体代码应该全部贴了出来,如有其他不明白可以下载demo看一下,具体的一些控件或者布局可以自行上网搜一下,或者看Dart、Flutter的官方文档。

如有不正确还望指正,共同进步。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值