Flutter学习7-列表ListView用法(横向滚动,下拉刷新,上拉加载)

Flutter学习7-列表ListView用法(横向滚动,下拉刷新,上拉加载)ListView是Flutter中的列表组件,可以横向也可以垂直ListView常见用法ListView横向滚动和垂直滚动这部分还是直接写代码吧效果需要注意的是ListView横向滚动时,设置item

ListView是Flutter中的列表组件,可以横向也可以垂直

ListView 常见用法

ListView 横向滚动和垂直滚动

这部分还是直接写代码吧

class ListPageState extends State<ListPage> {
  bool isVertical = true;
  var list = ['上海','北京','深圳','天津','邯郸',];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('测试ListView'),
      ),
      body: ListView(
      //通过该属性,设置朝向是垂直还是横向
        scrollDirection: isVertical ? Axis.vertical : Axis.horizontal,
        children: [
          RaisedButton(
            onPressed: () {
              setState(() {
                isVertical = !isVertical;
              });
            },
            child: Text('点我切换方向'),
          ),
          ...buildListItem()
        ],
      ),
    );
  }

  List<Widget> buildListItem() {
    return list
        .map((e) => isVertical ? _buildVItem(e) : _buildHItem(e))
        .toList();
  }
//构建纵向列表item
  Widget _buildVItem(String cityNam) {
    return Container(
      margin: EdgeInsets.only(bottom: 5),
      padding: EdgeInsets.only(top: 10, bottom: 10),
      alignment: Alignment.center,
      decoration: BoxDecoration(color: Colors.green),
      child: Text(
        '$cityNam',
        style: TextStyle(
            fontSize: 20,
            fontWeight: FontWeight.bold,
            color: Colors.tealAccent),
      ),
    );
  }
//构建横向item
  Widget _buildHItem(String cityNam) {
    return Container(
      width: 100,
      height: 100,
      margin: EdgeInsets.only(right: 5),
      padding: EdgeInsets.only(right: 10, left: 10),
      alignment: Alignment.center,
      decoration: BoxDecoration(color: Colors.green),
      child: Text(
        '$cityNam',
        style: TextStyle(
            fontSize: 20,
            fontWeight: FontWeight.bold,
            color: Colors.tealAccent),
      ),
    );
  }
}

效果 Flutter学习7-列表ListView用法(横向滚动,下拉刷新,上拉加载)

需要注意的是ListView横向滚动时,设置item高度是不生效的,可以设置ListView的父布局高度,进行高度控制

ListView.builder()

这是一种简便的构建ListView方式 将上面的代码简单替换即可

      body: ListView.builder(
          itemCount: list.length,
          scrollDirection: Axis.vertical,
          itemBuilder: (BuildContext context, int index) {
            return _buildVItem(list[index]);
          }),

可折叠的List(ExpansionTile)

实现类似QQ里面联系人分组的界面,可以使用ExpansionTile实现

class ExpandPage extends StatefulWidget {
  @override
  State<ExpandPage> createState() {
    return ExpandPageState();
  }
}

class ExpandPageState extends State<ExpandPage> {
  var list = {
    '中国': ['上海', '北京', '深圳', '天津', '邯郸',],
    'China': ['上海', '北京', '深圳', '天津', '邯郸',],
    'CN': ['上海', '北京', '深圳', '天津', '邯郸',]
  };

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('测试可展开的ListView'),
      ),
      body: ListView.builder(
          itemCount: list.keys.length,
          scrollDirection: Axis.vertical,
          itemBuilder: (BuildContext context, int index) {
            return _buildVItem(index);
          }),
    );
  }

  Widget _buildVItem(int index) {
    String countyName = list.keys.elementAt(index);
    var listCity = list[countyName];
    return ExpansionTile(
      leading: Icon(Icons.agriculture),
      subtitle: Text("副标题"),
      title: Text(
        countyName,
        style: TextStyle(fontSize: 20, color: Colors.teal),
      ),
      children: _buildExpandItem(listCity),
    );
  }

  List<Widget> _buildExpandItem(List<String> listCity) {
    return listCity
        .map((e) => FractionallySizedBox(
              widthFactor: 1,
              child: Container(
                padding: EdgeInsets.only(top: 10, bottom: 10),
                decoration: BoxDecoration(color: Colors.pink),
                child: Text(
                  e,
                  style: TextStyle(fontSize: 18, color: Colors.white),
                ),
              ),
            ))
        .toList();
  }
}

效果

Flutter学习7-列表ListView用法(横向滚动,下拉刷新,上拉加载)

也可以使用ExpansionPanelList实现

GridView 网格布局

Flutter中实现网格布局使用GridView实现

  • scrollDirection 控制GridView方向
  • gridDelegate 控制GridView的字widget的创建方式,主轴和交叉轴方向的间距以及子widget的宽高比
  • child 是子widget的list,注意改list中的widget设置的宽高是不生效的,子widget的宽高比已经由 gridDelegate 控制了
class GridPage extends StatefulWidget {
  @override
  State<GridPage> createState() {
    return GridPageState();
  }
}

class GridPageState extends State<GridPage> {
  bool isVertical = true;
  var list = [ '上海', '北京', '深圳', '天津', '邯郸', ];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('测试GridView'),
      ),
      body: GridView(
        padding: EdgeInsets.all(0),//边距
        scrollDirection: Axis.vertical,//是垂直滚动还是横向滚动
        //GridView的子Item的创建方式
        //SliverGridDelegateWithFixedCrossAxisCount :交叉轴上子widget的数量创建方式
        //SliverGridDelegateWithMaxCrossAxisExtent:主轴上固定宽或高的创建方式
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 4,//交叉轴上子widget的数量,
            mainAxisSpacing: 1,//主轴方向上子widget之间的间距
            crossAxisSpacing: 1,//交叉轴方向上子widget之间的间距
            childAspectRatio: 1),//子widget的交叉轴/主轴,它是宽高比或者高宽比
        children: buildListItem(),
      ),
      // body: GridView(
      // padding: EdgeInsets.zero,
      // scrollDirection: Axis.vertical,
      // gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
      // maxCrossAxisExtent: 240,//交叉轴方向上最大宽或高
      // crossAxisSpacing: 1,
      // childAspectRatio: 2,
      // mainAxisSpacing: 1),
      // children: buildListItem(),
      // ),
    );
  }

  List<Widget> buildListItem() {
    return list.map((e) => _buildVItem(e)).toList();
  }

  Widget _buildVItem(String cityNam) {
    return Container(
      padding: EdgeInsets.only(top: 10, bottom: 10),
      alignment: Alignment.center,
      decoration: BoxDecoration(color: Colors.green),
      child: Text(
        '$cityNam',
        style: TextStyle(
            fontSize: 20,
            fontWeight: FontWeight.bold,
            color: Colors.tealAccent),
      ),
    );
  }
}

效果

Flutter学习7-列表ListView用法(横向滚动,下拉刷新,上拉加载)

RefreshIndicator 下拉刷新组件

RefreshIndicator 是Flutter官方提供的下拉刷新组件,RefreshIndicator搭配ListView或GridView的时候 方向必须是垂直滚动的,横向的无效的,

RefreshIndicator构造分析

  • onRefresh 必要参数,是返回值类型为Future的回调Future Function(),当用户下拉组件时会回调到该方法中,这个时候一般会进行http请求,数据库读写等操作,
  • child 下拉刷新的子widget,一般为ListView或CustomScrollView
//模拟两秒后返回数据
  Future<Null> _handRefresh() async{
    await Future.delayed(Duration(seconds: 2));
    setState(() {
      list=list.reversed.toList();
    });
  }

ListView 中

Flutter学习7-列表ListView用法(横向滚动,下拉刷新,上拉加载)

GridView中 Flutter学习7-列表ListView用法(横向滚动,下拉刷新,上拉加载)

列表加载更多

Flutter官方并没有像refresh下拉刷新那样提供组件,需要通过监听列表滚动的距离是否到底部手动触发加载更多,

  1. 自定义ScrollController
  ScrollController _scrollController;

  @override
  void initState() {
    super.initState();
    _scrollController = ScrollController();
    _scrollController.addListener(() {
      if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
        print("开始加载更多");
        _handLoadMore();
      }
    });
  }
  1. 触发加载更多
 _handLoadMore() async {
    await Future.delayed(Duration(seconds: 15));
    setState(() {
      var newData = List<String>.from(list);
      list.addAll(newData);
    });
  }
  1. 将Scroller设置给ListView
ListView( controller: _scrollController,XXX)

如果上下反复滚动会多次触发该方法,需要自定义状态进行加载更多的控制

今天的文章Flutter学习7-列表ListView用法(横向滚动,下拉刷新,上拉加载)分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/16341.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注