美文网首页
Flutter的上下求索——ListView

Flutter的上下求索——ListView

作者: 云醉倚清风 | 来源:发表于2019-10-10 16:49 被阅读0次

一:理解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中定义好

现在只是学习基础知识,有问题或新的学习心得会继续补充......

相关文章

网友评论

      本文标题:Flutter的上下求索——ListView

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