介绍
itemExtent
:该参数如果不为null
,则会强制children
的“长度”为itemExtent
的值;这里的“长度”是指滚动方向上子组件的长度,也就是说如果滚动方向是垂直方向,则itemExtent
代表子组件的高度;如果滚动方向为水平方向,则itemExtent
就代表子组件的宽度。在ListView
中,指定itemExtent
比让子组件自己决定自身长度会更高效,这是因为指定itemExtent
后,滚动系统可以提前知道列表的长度,而无需每次构建子组件时都去再计算一下,尤其是在滚动位置频繁变化时(滚动系统需要频繁去计算列表高度)。shrinkWrap
:该属性表示是否根据子组件的总长度来设置ListView
的长度,默认值为false
。默认情况下,ListView
会在滚动方向尽可能多的占用空间。当ListView
在一个无边界(滚动方向上)的容器中时,shrinkWrap
必须为true
。addAutomaticKeepAlives
:该属性表示是否将列表项(子组件)包裹在AutomaticKeepAlive
组件中;典型地,在一个懒加载列表中,如果将列表项包裹在AutomaticKeepAlive
中,在该列表项滑出视口时它也不会被GC(垃圾回收),它会使用KeepAliveNotification
来保存其状态。如果列表项自己维护其KeepAlive
状态,那么此参数必须置为false
。addRepaintBoundaries
:该属性表示是否将列表项(子组件)包裹在RepaintBoundary
组件中。当可滚动组件滚动时,将列表项包裹在RepaintBoundary
中可以避免列表项重绘,但是当列表项重绘的开销非常小(如一个颜色块,或者一个较短的文本)时,不添加RepaintBoundary
反而会更高效。和addAutomaticKeepAlive
一样,如果列表项自己维护其KeepAlive
状态,那么此参数必须置为false
。
ListView.builder
ListView.builder
适合列表项比较多(或者无限)的情况,因为只有当子组件真正显示的时候才会被创建,也就说通过该构造函数创建的ListView
是支持基于Sliver的懒加载模型的。
itemBuilder
:它是列表项的构建器,类型为IndexedWidgetBuilder
,返回值为一个widget。当列表滚动到具体的index
位置时,会调用该构建器构建列表项。itemCount
:列表项的数量,如果为null
,则为无限列表。ListView.separated
ListView.separated
可以在生成的列表项之间添加一个分割组件,它比
ListView.builder
多了一个separatorBuilder
参数,该参数是一个分割组件生成器。
ListView默认构造方式
return ListView( children: <Widget>[ ListTile( leading: Image.network('https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2621765685,1081572519&fm=26&gp=0.jpg'), title: Text('我和我的祖国'), subtitle: Text('我和我的祖国,一刻也不能分隔'), ), ListTile( title: Text('我和我的祖国'), subtitle: Text('我和我的祖国,一刻也不能分隔'), trailing: Image.network('https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2621765685,1081572519&fm=26&gp=0.jpg'), ), ListTile( leading: Icon(Icons.accessibility_new,color: Colors.red,), title: Text('我和我的祖国'), subtitle: Text('我和我的祖国,一刻也不能分隔'), ), ], );
上面的代码也可以封装出来调用
List<Widget> _getData(){ return [ListTile( leading: Image.network('https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2621765685,1081572519&fm=26&gp=0.jpg'), title: Text('我和我的祖国'), subtitle: Text('我和我的祖国,一刻也不能分隔'), ), ListTile( title: Text('我和我的祖国'), subtitle: Text('我和我的祖国,一刻也不能分隔'), trailing: Image.network('https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2621765685,1081572519&fm=26&gp=0.jpg'), ), ListTile( leading: Icon(Icons.accessibility_new,color: Colors.red,), title: Text('我和我的祖国'), subtitle: Text('我和我的祖国,一刻也不能分隔'), )]; } @override Widget build(BuildContext context) { return ListView( children: this._getData() ); }
ListView.builder
@override Widget build(BuildContext context) { // TODO: implement build List<String>list=new List(); for(int i=0;i<4;i++){ list.add("我和我的祖国$i"); } return ListView.builder( itemCount: list.length, itemExtent: 40, itemBuilder: (BuildContext context,int dex){ return ListTile( title: Text( '${list[dex]}' ), ); }, ); }
ListView.separated
return ListView.separated( separatorBuilder: (BuildContext context,int dex){ return Divider( color: Colors.blue, height: 1, ); }, itemCount: list.length, itemBuilder: (BuildContext context,int dex){ return ListTile( title: Text( '${list[dex]}' ), ); }, ); }
做一个练习:
假如现在有一组数据
List _list=[ { 'head':'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2621765685,1081572519&fm=26&gp=0.jpg', 'title':'我和我的祖国', 'content':'我和我的祖国,一刻也不能分隔', }, { 'head':'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2621765685,1081572519&fm=26&gp=0.jpg', 'title':'我和我的祖国', 'content':'我和我的祖国,一刻也不能分隔', }, { 'head':'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2621765685,1081572519&fm=26&gp=0.jpg', 'title':'我和我的祖国', 'content':'我和我的祖国,一刻也不能分隔', } ];然后再把ListTile进行封装
Widget _getListTile(index){ return ListTile( leading: Image.network(_list[index]["head"]), title: Text( _list[index]["title"], style: TextStyle( fontWeight: FontWeight.w700, ), ), subtitle: Text( _list[index]["content"], ), ); }全部代码:
import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('这是我的FlutterAPP'), centerTitle: true, backgroundColor: Colors.red, textTheme: TextTheme( title: TextStyle( fontSize: 18, color: Colors.yellow, fontStyle: FontStyle.italic ) ), ), body: HomeText(), ), // theme: ThemeData( // primarySwatch: Colors.blue // ), ); } } class HomeText extends StatelessWidget { List _list=[ { 'head':'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2621765685,1081572519&fm=26&gp=0.jpg', 'title':'我和我的祖国', 'content':'我和我的祖国,一刻也不能分隔', }, { 'head':'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2621765685,1081572519&fm=26&gp=0.jpg', 'title':'我和我的祖国', 'content':'我和我的祖国,一刻也不能分隔', }, { 'head':'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2621765685,1081572519&fm=26&gp=0.jpg', 'title':'我和我的祖国', 'content':'我和我的祖国,一刻也不能分隔', } ]; Widget _getListTile(index){ return ListTile( leading: Image.network(_list[index]["head"]), title: Text( _list[index]["title"], style: TextStyle( fontWeight: FontWeight.w700, ), ), subtitle: Text( _list[index]["content"], ), ); } @override Widget build(BuildContext context) { return ListView.separated( separatorBuilder: (BuildContext context,index){ return Divider( height: 10, color: Colors.green, ); }, itemCount: _list.length, itemBuilder: (BuildContext context,index){ return _getListTile(index); }, ); } }