一:理解ListView
语言 | 控件名 | 显示方法 | 点击方法 |
---|---|---|---|
iOS | tableView | numberOfRowsInSection/cellForRowAtIndexPath | didSelectRowAtIndexPath |
Android | ListView | setAdapter() | setOnItemClickListener |
Flutter | ListView | children | GestureDetector 包裹元素 onTap |
像iOS 中还有UICollectionView,除了layout的生成,其他与tableView大同小异。Android常用的还有RecyclerView,也需要实现adapter。Flutter的ListView很好理解,ListView中有个children属性ListView(children: <Widget>[]),其中是个Widget数组。
二:简单使用ListView
新建个home.dart,参考Flutter的上下求索——导航/页面切换
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Home Page'),
),
body: new Center(
child: new ListView(children: getTextData())
),
);
}
getTextData() {
List<Widget> widgets = [];
for (int i = 0; i < 100; i++) {
widgets.add(Text("${i}"));
}
return widgets;
}
}
普通文本ListView.jpg
三:自定义“Cell”
首先对于iOS 中cell的认识,就是能实现UX想要的各式各样(折磨人)的自定义展示。每个cell,可重用单元格,可以用代码,使用xib去自定义,Android中使用xml描述样式,通过adapter去赋值呈现。ListView不论在哪种语言中,都不会需要展示多少个最小单位,就生成多少个 ,这是资源的浪费。Flutter中视图对象最小的单位是Widget。
import 'package:flutter/material.dart';
class CustomCell extends StatelessWidget {
// 类似iOS中init初始化方法的重新
const CustomCell({
Key key,
this.color: const Color(0xFF2DBD3A),
this.child,
}) : super(key: key);
//属性声明
final Color color;
final Widget child;
@override
Widget build(BuildContext context) {
return new Container(
color: color,
child: child,
height: 100,
);
}
}
home.dart中添加新方法 ,替换 ListView(children: getTextData())
getCustomData() {
List<Widget> widgets = [];
for (int i = 0; i < 20; i++) {
widgets.add(new CustomCell(color: i%2==0?Colors.blueGrey:Colors.amber,child: Text("${i}")));
}
return widgets;
}
自定义Cell.jpg
四:制作我们想要的学习列表
继续在cell.dart中新建一个有首部标题和尾部标题的Cell,仿写iOS的默认cell
class NavigationCell extends StatelessWidget {
const NavigationCell({
Key key,
this.labelTitle: "默认标题",
this.detailLabelTitle: "默认尾部标题",
}) : super(key: key);
//属性声明
final String labelTitle;
final String detailLabelTitle;
@override
Widget build(BuildContext context) {
return new Container(
child: new Column(
children: <Widget>[
new Row(children: <Widget>[
new Padding(
padding: new EdgeInsets.only(left: 15),
child: new Text(this.labelTitle,
style: new TextStyle(color: Colors.black, fontSize: 24))),
new Padding(
padding: new EdgeInsets.only(right: 15),
child: new Row(
children: <Widget>[
new Text(this.detailLabelTitle,
style: new TextStyle(color: Colors.grey, fontSize: 16)),
new Icon(IconData(0xebc7, fontFamily: 'IconFont'), size: 16)
],
))
], mainAxisAlignment: MainAxisAlignment.spaceBetween),
new Divider()
],
),
height: 50,
);
}
}
这里的布局代码其实是想着敲,然后结合api,再搜索资料试出来的。因为热重载可以很容易看见布局修改的效果。这里其实就是容器套列,列套行。为何用列,因为需要下部有个横线。
Widget build(BuildContext context) {
return new Container(
child: new Column(
children: <Widget>[
new Row(children: <Widget>[ ],
new Divider()
],
)
);
}
// home.dart中新增的方法
getNavigationData(){
List<String> titles = ["导航","列表"];
List<Widget> widgets = [];
for (int i = 0; i < titles.length; i++) {
widgets.add(new NavigationCell(labelTitle: titles[i],detailLabelTitle: "${i}",));
}
return widgets;
}
布局图示
效果
五:ListItem的点击
需要给cell控件外层包个GestureDetector
getNavigationData(BuildContext context) {
List<Widget> widgets = [];
List directory = getDirectory();
for (int i = 0; i < directory.length; i++) {
widgets.add(new GestureDetector(
child: new NavigationCell(
labelTitle: directory[i]["title"],
detailLabelTitle: directory[i]["detailInfo"],
),
onTap: () {
Navigator.of(context).pushNamed(directory[i]["router"]);
},
));
}
return widgets;
}
getDirectory() {
return [
{"title": "导航", "detailInfo": "Navigation", "router": "/first"},
{"title": "按钮", "detailInfo": "Button", "router": ""},
{"title": "导航", "detailInfo": "Navigation", "router": ""},
{"title": "导航", "detailInfo": "Navigation", "router": ""},
{"title": "导航", "detailInfo": "Navigation", "router": ""},
{"title": "导航", "detailInfo": "Navigation", "router": ""},
{"title": "导航", "detailInfo": "Navigation", "router": ""},
{"title": "导航", "detailInfo": "Navigation", "router": ""},
{"title": "导航", "detailInfo": "Navigation", "router": ""},
{"title": "导航", "detailInfo": "Navigation", "router": ""}
];
}
效果图
其中
Navigator.of(context).pushNamed 需要在main.dart的routes中定义好
现在只是学习基础知识,有问题或新的学习心得会继续补充......
网友评论