「这是我参与11月更文应战的第4天,活动概况检查:2021最终一次更文应战」

咱们在开发中,经常会需求显现列表,在iOS中咱们运用UITableView来完成列表,那么在Flutter中,对应的部件为ListView;咱们运用ListView来开始完成一个简略的列表界面;

ListView的运用

model模型

已然要显现一个列表,那么咱们就需求在列表中显现一个数据模型,这儿咱们创立一个article.dart文件,在其间创立一个模型:

class Article {
  const Article(this.name, this.iconUrl); // 结构函数
  final String name;
  final String iconUrl;
}

模型的创立办法还有另外一种,如下:

class Article {
  const Article({this.name, this.iconUrl}); // 结构函数 可选赋值
  final String? name; // ? 表示空安全
  final String? iconUrl;
}

那么,这两种创立办法有什么区别呢?

  • const Article(this.name, this.iconUrl);是一个结构函数,初始化nameiconUrl有必要赋值;
  • const Article({this.name, this.iconUrl});也是一个结构函数,其初始化时nameiconUrl可以不进行赋值,可是此刻需求留意有必要满意以下两个条件中的任一个:
    • nameiconUrl有必要有默认值;
    • nameiconUrl设置为空安全;

List数据源

为了方便,咱们直接在article.dart文件中创立一个数组,来寄存Article类作为列表的数据源;

final List<Article> datas = [] // 具体内容没有放出来

此刻,article.dart文件如下:

Flutter(六)常用部件-ListView初体验

ListView

在运用之前,咱们首先需求知道假如创立ListView,咱们在运用ListView的时分一般不直接进行结构创立,而是运用其命名结构函数进行创立;创立代码如下:

ListView.builder(itemBuilder: itemBuilder)

builder就是在创立ListView的时分,咱们需求一个烘托;itemBuilder是一个办法回调;依据其定义

required IndexedWidgetBuilder itemBuilder,

咱们了解到其回来的是IndexedWidgetBuilder

typedef IndexedWidgetBuilder = Widget Function(BuildContext context, int index);

此函数回来了一个Widget,咱们留意到,函数中有两个参数contextindex,这个时分,依据以往iOS开发经历,咱们立刻意识到其作用类似于UITableView中的cellForRow办法; ​

咱们依据此函数,创立一个回来Widget的办法:

	Widget _itemForRow(BuildContext context, int index) {
    return null
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter 工程'),
      ),
      body: ListView.builder(
          itemBuilder: _itemForRow,
          itemCount: datas.length,
      ),
    );
  }
  • _表示内部拜访,文件内部!
  • _itemForRow办法回来每一个cell的视图;
  • itemCount办法传递整个列表中数据个数;

显现文章标题

咱们先简略回来一个Text部件显现文章标题:

Widget _itemForRow(BuildContext context, int index) {
    return Text(datas[index].name);
}

留意,假如name特点为空安全的,那么此刻需求进行强制解包:

Widget _itemForRow(BuildContext context, int index) {
    return Text(datas[index].name!);
}

运行作用:

Flutter(六)常用部件-ListView初体验

显现封面图片

加载图片时,咱们运用Image部件;

Image.network(’‘)

咱们将_itemForRow函数代码修正如下:

  Widget _itemForRow(BuildContext context, int index) {
    return Container(
      color: Colors.white,
      margin: const EdgeInsets.all(10),
      child: Image.network(datas[index].iconUrl),
    );
  }

Container是一个常用的小部件,方便咱们进行布局

显现作用:

Flutter(六)常用部件-ListView初体验

显现标题和封面

咱们发现Container部件的child只能显现一个部件,这样咱们就不能一起显现文章的标题和封面了; ​

那么,有没有一个部件,它可以寄存多个部件呢?咱们希望在封面的下方能显现出标题,封面和标题竖着排列,这个时分,就有Column部件可以到达这个作用,并且Column部件有children特点是个数组,可以一起寄存多个部件:

  Widget _itemForRow(BuildContext context, int index) {
    return Container(
      color: Colors.white,
      margin: const EdgeInsets.all(10),
      child: Column(
        children: [
          Image.network(datas[index].iconUrl),
          Container(height: 10,),
          Text(
            datas[index].name,
            style: const TextStyle(
              fontSize: 20,
          ),)
        ],
      ),
    );
  }

Container(height: 10,), :封面与标题之间间隔10像素的间隔,同样的作用SizedBox部件或许完成;

作用如下:

Flutter(六)常用部件-ListView初体验
完整代码如下:

class ListViewDemo extends StatelessWidget {
  // _的内部是指 文件内部!
  Widget _itemForRow(BuildContext context, int index) {
    return Container(
      color: Colors.white,
      margin: const EdgeInsets.all(10),
      child: Column(
        children: [
          Image.network(datas[index].iconUrl),
          const SizedBox(height: 10,),
          Text(
            datas[index].name,
            style: const TextStyle(
              fontWeight: FontWeight.w800,
              fontSize: 20,
            ),)
        ],
      ),
    );
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey,
      appBar: AppBar(
        title: const Text('ListView的运用'),
      ),
      body: ListView.builder(
        itemBuilder: _itemForRow,
        itemCount: datas.length,
      ),
    );
  }
}

Flutter小常识

部件的布局只要三种:

  • 竖着
  • 横着
  • 叠着