7.1-Flutter中列表组件ListView

基于ListView实现水平和垂直方向滚动列表

实现垂直滚动列表

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

const CITY_NAMES = ['北京', '上海', '广州', '深圳', '海南', '杭州', '苏州', '温州'];

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(title: Text('ListView'),),
        body: ListView(
          children: _buildList(),
        ),
      ),
    );
  }

  List _buildList() {
    return CITY_NAMES.map((city) => _item(city)).toList();
  }

  Widget _item(String city) {
    return Container(
      height: 80,
      margin: EdgeInsets.only(bottom: 5),
      alignment: Alignment.center,
      decoration: BoxDecoration(color: Colors.teal),
      child: Text(
        city,
        style: TextStyle(color: Colors.white, fontSize: 20),
      ),
    );
  }

}

也可以使用ListView.Builder更加高效的实现列表(适用于动态列表或者数据来给你较大时)

      home: Scaffold(
        appBar: AppBar(title: Text('ListView'),),
        body: ListView.builder(
          itemCount: CITY_NAMES.length,
          itemBuilder: (BuildContext context, int position) {
            return _buildList()[position];
          },
        ),
      ),

实现水平滚动列表

水平滚动只需要为ListView添加scrollDirection: Axis.horizontal参数即可

      home: Scaffold(
        appBar: AppBar(title: Text('ListView'),),
        body: ListView(
          scrollDirection: Axis.horizontal,
          children: _buildList(),
        ),
      ),
  • 为ListView设置高度需要对ListView外层Container设置高度

基于ExpansionTitle实现可展开的列表

ExpansionTitle基本知识

const ExpansionTile({
    Key key,
    this.leading,//标题左侧要展示的widget
    @required this.title,//要展示的标题widget(是整个标题父控件)
    this.backgroundColor,//背景
    this.onExpansionChanged,//列表展开收起的回调函数
    this.children = const [],//列表展开时显示的widget
    this.trailing,//标题右侧要展示的widget
    this.initiallyExpanded = false,//是否默认状态下展开
  }) : assert(initiallyExpanded != null),
       super(key: key);
  • 数据要求

    const CITY_NAMES = {
      '北京': ['东城区', '西城区', '丰台区', '海淀区', '房山区'],
      '上海': ['黄埔区', '徐汇区', '虹口区'],
      '杭州': ['上城区', '下城区']
    };
    
  • ExpansionTitle

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    const CITY_NAMES = {
      '北京': ['东城区', '西城区', '丰台区', '海淀区', '房山区'],
      '上海': ['黄埔区', '徐汇区', '虹口区'],
      '杭州': ['上城区', '下城区']
    };
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'ExpansionTile Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: Scaffold(
            appBar: AppBar(title: Text('ListView'),),
            body: ListView(
              children: _buildList(),
            ),
          ),
        );
      }
    
      List _buildList() {
        List widgets = [];
        CITY_NAMES.keys.forEach((key) {
          widgets.add(_item(key, CITY_NAMES[key]));
        });
        return widgets;
      }
    
      Widget _item(String city, List subCities) {
        return ExpansionTile(
          title: Text(
            city,
            style: TextStyle(color: Colors.black54, fontSize: 20),
          ),
          children: subCities.map((subCities) => _buildSub(subCities)).toList(),
        );
      }
    
      Widget _buildSub(String subCity) {
        return FractionallySizedBox(//可伸缩(如果不设置FractionallySizedBox,子列表宽度无法撑满屏幕)
          widthFactor: 1,
          child: Container(
            height: 50,
            margin: EdgeInsets.only(bottom: 5),
            decoration: BoxDecoration(color: Colors.lightBlueAccent),
            child: Text(subCity),
          ),
        );
      }
    
    }
    
    image

基于GridView实现网格列表

GridView时flutter中用于展示网格布局风格的widget,通常使用GridView.count构造函数来创建一个GridView

与ListView用法一直,只需要使用GridView.count构建即可

      home: Scaffold(
        appBar: AppBar(title: Text('ListView'),),
        body: GridView.count(
          crossAxisCount: 2,//列数
          children: _buildList(),
        ),
      ),
image

高级功能列表下拉刷新与上拉加载更多

实现下拉刷新

使用RefreshIndicator实现列表的下拉刷新

实现上拉加载

借助ScrollController,为列表设置controller参数,通过ScrollController监听列表滚动的位置,实现加载更多功能

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

List cityNames = [
  '北京', '上海', '广州', '深圳', '海南', '杭州', '苏州', '温州', '泉州', '保定', '郑州', '唐山', '东京'];

class MyApp extends StatefulWidget {

  @override
  _MyAppState createState() => _MyAppState();

}

class _MyAppState extends State {

  ScrollController _scrollController = ScrollController();

  @override
  void initState() {
    _scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) { //当前位置等于可滚动位置
        _loadData();
      }
    });
    super.initState();
  }

  @override
  void dispose() {
    //在声明周期结束的时候将监听移除
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '下拉刷新',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
          appBar: AppBar(title: Text('ListView'),),
          body: RefreshIndicator(
              child: ListView(
                controller: _scrollController,
                children: _buildList(),
              ),
              onRefresh: _handleRefresh)
      ),
    );
  }


  List _buildList() {
    return cityNames.map((city) => _item(city)).toList();
  }

  Widget _item(String city) {
    return Container(
      height: 80,
      margin: EdgeInsets.only(bottom: 5),
      alignment: Alignment.center,
      decoration: BoxDecoration(color: Colors.teal),
      child: Text(
        city,
        style: TextStyle(color: Colors.white, fontSize: 20),
      ),
    );
  }

  Future _handleRefresh() async {
    await Future.delayed(Duration(seconds: 2));
    setState(() {
      cityNames = cityNames.reversed.toList();
    });
    return null;
  }

  _loadData() async {
    await Future.delayed(Duration(milliseconds: 200));
    setState(() {
      List list = new List .from(cityNames);
      list.addAll(cityNames);
      cityNames = list;
    });
  }

}
image

你可能感兴趣的:(7.1-Flutter中列表组件ListView)