页面简单分析
首先我们观察下,发现页面的是一个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,运行:
分割线
分割线可以使用下面的这个代码,Row布局分成两块针对性的设置颜色即可。
Row(children: [
Container(width: 50, height: 0.5, color: Colors.white),
Container(height: 0.5,color: Colors.grey)])
push跳转
点击cell的时候我们希望跳转到一个新的子页面,此时修改下cell的Build的方法.。引出了GestureDetector
这个新的Widget,里面有一个onTap
方法,我们在这里处理点击事件。
- onTap
- onTapDown:点下来
- onTapCancel:离开了
这里的Navigator._of_(context).push
的是一个Route<T>
的子类MaterialPageRoute
。而这个函数的构造需要一个bulider
继续点击发现是这个声明的类型:
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),
),
);
}
}
无状态修改成有状态
把这里的cell从无状态修改成有状态的:class _DiscoverCellState extends State<DiscoverCell>{}
在这里无法访问DiscoverCell
里面的成员,此时可以使用widget.title�
。
�