likes
comments
collection
share

Flutter实战-搭建微信项目(二)

作者站长头像
站长
· 阅读数 6

页面简单分析

首先我们观察下,发现页面的是一个ListView, 但是在写的时候尽量使用Container来包装一层,这样可以增加拓展性,类比iOS中的TabView.

接着上篇,那我们直接在发现页面修改:首先在AppBar新增一个centerTitle这个属性专门为安卓设计的,其次默认的AppBar是底部边缘是有一条线的,我们使用elevation = 0可以隐藏这条线。

  appBar: AppBar(
    centerTitle: true, // 这个属性专为安卓设计
    elevation: 0,
    title: Text('发现'),
  )

修改body为Container包装的ListView, 现在的代码成了这样

class _DiscoverPageState extends State<DiscoverPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        elevation: 0,
        title: Text('发现'),
      ),
      body: Container(
        child: ListView(),
      ),
    );
  }
}

定制Cell

好了,接着来自定义cell。首先默认先写一个无状态的Widget,后面如果涉及到状态会变更的话再修改。分析:

  • 暴露四个参数title titleImageName subTitle subImageName,我们可以使用下面四个来作为参数创建一个构造函数
  • 整体是个Row分成左右两块,在主轴左右两侧分开MainAxisAlignment.spaceBetween
  • 左右两块也是一个子Row.
  • sub属性是可选的所以语法可以使用三目运算符
  • 左边的图片和文字之间的间距可以使用SizedBox(width: 15)

所以此时的代码是这样的:

import 'package:flutter/material.dart';

class DiscoverCell extends StatelessWidget {
  final String title;
  final String titleImageName;
  final String? subTitle;
  final String? subImageName;

  DiscoverCell({
    required this.title,
    required this.titleImageName,
    this.subTitle,
    this.subImageName,
  })  : assert(title != null, 'title不能为空'),
        assert(titleImageName != null, 'titleImageName不能为空');

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Container(
              padding: EdgeInsets.all(10),
              child: Row(
                children: [
                  Image(
                    image: AssetImage(titleImageName),
                    width: 20,
                  ),
                  SizedBox(width: 15),
                  Text(title)
                ],
              )),
          Container(
              padding: EdgeInsets.all(10),
              child: Row(
                children: [
                  subTitle != null ? Text(subTitle!) : Text(''),
                  subImageName != null  ? Image.asset(subImageName!) : Container(),
                  Image(
                    image: AssetImage('images/icon_right.png'),
                    width: 15,
                  )
                ],
              ))
        ],
      ),
    );
  }
}

回到DiscoverPage页面,LIstView的Chidren设置上面定制的Widget,运行: ​

Flutter实战-搭建微信项目(二)

分割线

分割线可以使用下面的这个代码,Row布局分成两块针对性的设置颜色即可。

Row(children: [
         Container(width: 50, height: 0.5, color: Colors.white),
         Container(
           height: 0.5,
           color: Colors.grey,
         )
       ])

Flutter实战-搭建微信项目(二)

push跳转

点击cell的时候我们希望跳转到一个新的子页面,此时修改下cell的Build的方法.。引出了GestureDetector这个新的Widget,里面有一个onTap方法,我们在这里处理点击事件。

  • onTap
  • onTapDown:点下来
  • onTapCancel:离开了

Flutter实战-搭建微信项目(二) 这里的Navigator._of_(context).push的是一个Route<T>的子类MaterialPageRoute。而这个函数的构造需要一个bulider

Flutter实战-搭建微信项目(二) 继续点击发现是这个声明的类型:

final WidgetBuilder builder;
typedef WidgetBuilder = Widget Function(BuildContext context);

所以也就是一个含有BuildContext context参数的一个函数。

 Navigator.of(context).push(MaterialPageRoute(
            builder: (BuildContext context) => DiscoverChildPage(title: title)));

此时的DiscoverChildPage是一个新的子页面,需要一个参数title来作为appBar的title展示。

import 'package:flutter/material.dart';

class DiscoverChildPage extends StatelessWidget {
  final String title;
  DiscoverChildPage({required this.title});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child: Text(title),
      ),
    );
  }
}

Flutter实战-搭建微信项目(二)

无状态修改成有状态

把这里的cell从无状态修改成有状态的: class _DiscoverCellState extends State<DiscoverCell>{} 在这里无法访问DiscoverCell里面的成员,此时可以使用widget.title