美文网首页
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