美文网首页Flutter
7.1-Flutter中列表组件ListView

7.1-Flutter中列表组件ListView

作者: YangDxg | 来源:发表于2019-05-22 11:40 被阅读0次

    基于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<Widget> _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>[],//列表展开时显示的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<Widget> _buildList() {
          List<Widget> widgets = [];
          CITY_NAMES.keys.forEach((key) {
            widgets.add(_item(key, CITY_NAMES[key]));
          });
          return widgets;
        }
      
        Widget _item(String city, List<String> 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<String> cityNames = [
      '北京', '上海', '广州', '深圳', '海南', '杭州', '苏州', '温州', '泉州', '保定', '郑州', '唐山', '东京'];
    
    class MyApp extends StatefulWidget {
    
      @override
      _MyAppState createState() => _MyAppState();
    
    }
    
    class _MyAppState extends State<MyApp> {
    
      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<Widget> _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<Null> _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<String> list = new List <String>.from(cityNames);
          list.addAll(cityNames);
          cityNames = list;
        });
      }
    
    }
    
    image

    相关文章

      网友评论

        本文标题:7.1-Flutter中列表组件ListView

        本文链接:https://www.haomeiwen.com/subject/zzuyzqtx.html