Flutter之 ListView组件使用示例详解

  class MyListViewPage extends StatefulWidget {

  const MyListViewPage({Key? key}) : super(key: key);

  @override

  _MyListViewPageState createState() => _MyListViewPageState();

  }

  class _MyListViewPageState extends State {

  static const loadingTag = "##loading##"; //表尾标记

  final _words = [loadingTag];

  @override

  void initState() {

  // TODO: implement initState

  super.initState();

  _retrieveData();

  }

  @override

  Widget build(BuildContext context) {

  return Scaffold(

  appBar: getAppBar('ListView'),

  body: Container(

  color: Colors.black.withOpacity(0.2),

  child: _buildInfinite(),

  ),

  );

  }

  _buildDefault() {

  return ListView(

  shrinkWrap: false,

  padding: const EdgeInsets.all(20.0),

  children: const [

  Text('I'm dedicating every day to you'),

  Text('Domestic life was never quite my style'),

  Text('When you smile, you knock me out, I fall apart'),

  Text('And I thought I was so smart'),

  ],

  );

  }

  _buildBuilder() {

  return ListView.builder(

  itemCount: 100,

  itemExtent: 50, //强制高度为50.0

  itemBuilder: (BuildContext context, int index) {

  return ListTile(

  leading: const Icon(Icons.person),

  title: Text('$index'),

  );

  });

  }

  _buildSeparated() {

  //下划线widget预定义以供复用。

  Widget divider1 = Divider(

  color: Colors.blue,

  );

  Widget divider2 = Divider(color: Colors.green);

  return ListView.separated(

  scrollDirection: Axis.vertical,

  //列表项构造器

  itemBuilder: (BuildContext context, int index) {

  return ListTile(title: Text("$index"));

  },

  //分割器构造器

  separatorBuilder: (BuildContext context, int index) {

  return index % 2 == 0 ? divider1 : divider2;

  },

  itemCount: 100);

  }

  _buildExtent() {

  return ListView.builder(

  prototypeItem: const ListTile(

  title: Text('1'),

  ),

  itemBuilder: (BuildContext context, int index) {

  //LayoutLogPrint是一个自定义组件,在布局时可以打印当前上下文中父组件给子组件的约束信息

  return Center(child: Text('$index'),);

  });

  }

  //无限加载列表

  _buildInfinite(){

  return ListView.separated(

  itemBuilder: (context,index){

  //如果到了表尾

  if(_words[index] ==loadingTag) {

  //如果数据不足100条

  if (_words.length <= 100) {

  //拉去数据

  _retrieveData();

  //加载显示loading

  return Container(

  padding: const EdgeInsets.all(16),

  alignment: Alignment.center,

  child: const SizedBox(

  width: 24,

  height: 24,

  child: CircularProgressIndicator(strokeWidth: 2,),

  ),

  );

  } else {

  //已经加载100不再获取数据

  return Container(

  alignment: Alignment.center,

  padding: const EdgeInsets.all(16),

  child: const Text('没有更多了',

  style: TextStyle(color: Colors.grey),),

  );

  }

  }

  return ListTile(title: Text(_words[index]),);

  },

  separatorBuilder:(context,index)=>Divider(height:1,color: Colors.black,),

  itemCount: _words.length);

  }

  void _retrieveData(){

  Future.delayed(Duration(seconds: 5)).then((value){

  setState(() {

  _words.insertAll(_words.length-1,

  //每次生成20个单词

  List.generate(20, (index){

  return 'words $index';

  }));

  });

  });

  }

  }