Flutter列表组件(ListView,GrideView)

Flutter列表组件

    • ListView介绍
      • ListView参数列表
      • 基本列表
        • 垂直列表
        • 水平列表
      • 动态列表
        • ListView.builder遍历数据生成列表
    • GrideView组件
      • 参数说明
      • GrideView.builder遍历数据生成列表

ListView介绍

Flutter 中我们可以通过 ListView 来定义列表项,支持垂直和水平方向展示。通过一个属性就可以控制列表的显示方向。列表有一下
分类:
1、垂直列表
2、垂直图文列表
3、水平列表
4、动态列表
5、矩阵式列表

ListView参数列表

名称 类型 说明
scrollDirection Axis Axis.horizontal 水平列
Axis.vertical 垂直列表(默认)
padding EdgeInsetsGeometry 内边距
resolve bool 组件反向排序
children List< Widget> 列表元素

基本列表

对于ListTile组件我的理解是相当于我们以前Java Android时列表中的单个条目,不过Flutter已经帮我们封装好了,条目中有以下几个常用属性

    this.leading,   //放在条目前面(左边)的图片
    this.title,     //条目的主标题
    this.subtitle,  //条目的副标题
    this.trailing,  //放在条目后面(右边)的图片

children: < Widget>[ …]中返回的的是一个组件集合,里面包含多个组件,每个子组件就相当于我们列表中的一个条目,常与ListTile组件结合显示类似新闻列表

垂直列表
// ignore_for_file: non_constant_identifier_names, prefer_const_constructors

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Demo'),
        ),
        body: const HomeContent(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  const HomeContent({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView(
      padding:EdgeInsets.all(10),
      children: <Widget>[
        ListTile(
          leading: Icon(Icons.ac_unit,size: 30,),
          title: Text("解决github下载速度慢问题"),
          subtitle: Text("我们需要从github拉取一套代码到我们本地,我们国内下载速度非常慢,现在分享一种解决方案提高下载速度。"),
        ),
          ListTile(
            leading: Image.asset("images/a.jpg",),
          title: Text("final属性值能被反射修改吗?"),
          subtitle: Text("有网友询问反射给final修饰的字段设值,为啥设值会失败,之前也深入学习一下反射。"),
        ),
          ListTile(
            leading: Icon(Icons.access_time_filled,color: Colors.yellow,),
          title: Text("当Jetpack Compose遇到Navigation"),
          subtitle: Text("Jetpack Compose作为一个声明式UI框架经常拿来与React 、Flutter等作对比"),
        ),
          ListTile(
          title: Text("Android Canvas画布解析"),
          subtitle: Text("在开发中,我们经常需要自定义View去实现各种各样的效果,经常需要用到Canvas画布去绘制各种各样的图形和图案"),
          trailing: Icon(Icons.access_time_sharp),
        ),
      ],
    );
  }
}

Flutter列表组件(ListView,GrideView)_第1张图片

水平列表

注意:下边例子中我们在listview外部又加了一个Container,原因是当我们设置方向为水平时,条目中高度属性会失效,默认为对齐父组件,因此我们在listview外部又加了一个Container,然后指定高度,这样listview高度就被限制。同样的在垂直方向时listview内部条目默认宽度于父布局一致,设置宽度无效
这里listview里面用的是container组件展示每个条目

// ignore_for_file: non_constant_identifier_names, prefer_const_constructors

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Demo'),
        ),
        body: const HomeContent(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  const HomeContent({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
        height: 200.0,
        margin: EdgeInsets.all(5),
        child: ListView(
        //设置列表为水平列表
          scrollDirection: Axis.horizontal,
          children: <Widget>[
            Container(
              width: 180.0,
              color: Colors.lightBlue,
            ),
            Container(
                width: 180.0,
                color: Colors.amber,
                child: ListView(
                  children: <Widget>[
                    Image.network(
                        'https://cdn.stocksnap.io/img-thumbs/960w/flower-bouquet_X6UBKGVU0Z.jpg'),
                    SizedBox(height: 16.0),
                    Text(
                      '这是一个文本信息',
                      textAlign: TextAlign.center,
                      style: TextStyle(fontSize: 16.0),
                    )
                  ],
                )),
            Container(
              width: 180.0,
              color: Colors.deepOrange,
            ),
            Container(
              width: 180.0,
              color: Colors.deepPurpleAccent,
            ),
          ],
        ));
  }
}

Flutter列表组件(ListView,GrideView)_第2张图片

动态列表

// ignore_for_file: prefer_const_constructors, prefer_collection_literals, deprecated_member_use

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Demo'),
        ),
        body: const HomeContent(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  const HomeContent({Key? key}) : super(key: key);

  //自定义方法
  List<Widget> _getData() {
    List<Widget> list = [];
    for (var i = 0; i < 20; i++) {
      list.add(ListTile(
        title: Text("我是第$i个条目"),
      ));
    }
    return list;
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: _getData(),
    );
  }
}

Flutter列表组件(ListView,GrideView)_第3张图片
获取外部list生成列表(源码来自IT营)

  List listData=[
      {
          "title": 'Candy Shop',
          "author": 'Mohamed Chahin',
          "imageUrl": 'https://www.itying.com/images/flutter/1.png',
      },
       {
          "title": 'Childhood in a picture',
          "author": 'Google',
          "imageUrl": 'https://www.itying.com/images/flutter/2.png',
      },
      {
          "title": 'Alibaba Shop',
          "author": 'Alibaba',
          "imageUrl": 'https://www.itying.com/images/flutter/3.png',
      },
      {
          "title": 'Candy Shop',
          "author": 'Mohamed Chahin',
          "imageUrl": 'https://www.itying.com/images/flutter/4.png',
      },
       {
          "title": 'Tornado',
          "author": 'Mohamed Chahin',
          "imageUrl": 'https://www.itying.com/images/flutter/5.png',
      },
      {
          "title": 'Undo',
          "author": 'Mohamed Chahin',
          "imageUrl": 'https://www.itying.com/images/flutter/6.png',
      },
      {
          "title": 'white-dragon',
          "author": 'Mohamed Chahin',
          "imageUrl": 'https://www.itying.com/images/flutter/7.png',
      }      

  ];

// ignore_for_file: prefer_const_constructors, prefer_collection_literals, deprecated_member_use, unused_local_variable

import 'package:flutter/material.dart';
import 'res/listData.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Demo'),
        ),
        body: const HomeContent(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  const HomeContent({Key? key}) : super(key: key);

  //自定义方法
  List<Widget> _getData() {
    var list = <Widget>[];
    /*
    遍历外部listData获取数据生成listtile集合的两种方法
    */
    //第一种
    var tempList = listData.map((e) {
      return ListTile(
        leading: Image.network(e["imageUrl"]),
        title: Text(e["title"]),
        subtitle: Text(e["author"]),
      );
    });
    //第二种
    for (int i = 0; i < listData.length; i++) {
      list.add(ListTile(
        leading: Image.network(listData[i]["imageUrl"]),
        title: Text(listData[i]["title"]),
        subtitle: Text(listData[i]["author"]),
      ));
    }
    return list;
    //  return tempList.toList();
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: _getData(),
    );
  }
}

Flutter列表组件(ListView,GrideView)_第4张图片

ListView.builder遍历数据生成列表
// ignore_for_file: prefer_const_constructors, prefer_collection_literals, deprecated_member_use, unused_local_variable, must_be_immutable

import 'package:flutter/material.dart';
import 'res/listData.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Demo'),
        ),
        body: HomeContent(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  List list = [];
  HomeContent({Key? key}) : super(key: key) {
    for (var i = 0; i < 20; i++) {
      list.add("我是第$i个条目");
    }
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        itemCount: list.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(list[index]),
          );
        });
  }
}

Flutter列表组件(ListView,GrideView)_第5张图片
使用外部数据

// ignore_for_file: prefer_const_constructors, prefer_collection_literals, deprecated_member_use, unused_local_variable, must_be_immutable

import 'package:flutter/material.dart';
import 'res/listData.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Demo'),
        ),
        body: HomeContent(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  const HomeContent({Key? key}) : super(key: key);

  Widget _getListData(context, index) {
    return ListTile(
      leading: Image.network(listData[index]["imageUrl"]),
      title: Text(listData[index]["title"]),
      subtitle: Text(listData[index]["author"]),
    );
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        itemCount: listData.length,
        //注意这里是赋值不是调用方法,因此不加()
        itemBuilder: _getListData
        );
  }
}

Flutter列表组件(ListView,GrideView)_第6张图片

GrideView组件

当数据量很大的时候用矩阵方式排列比较清晰。此时我们可以用网格列表组
件 GridView 实现布局。
GridView 创建网格列表有多种方式,下面我们主要介绍两种。

  1. 可以通过 GridView.count 实现网格布局
  2. 通过 GridView.builder 实现网格布局

参数说明

名称 类型 说明
scrollDirection Axis 滚动方法
padding EdgeInsetsGeometry 内边距
resolve bool 组件反向排序
crossAxisSpacing double 水平子 Widget 之间间距
mainAxisSpacing double 垂直子 Widget 之间间距
crossAxisCount int 一行的 Widget 数量
childAspectRatio double 子 Widget 宽高比例
children < Widget>[ ]
gridDelegate (常用)SliverGridDelegateWithFixedCrossAxisCount
SliverGridDelegateWithMaxCrossAxisExtent
控制布局主要用在GridView.builder 里面
// ignore_for_file: prefer_const_constructors, prefer_collection_literals, deprecated_member_use, unused_local_variable, must_be_immutable

import 'package:flutter/material.dart';
import 'res/listData.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Demo'),
        ),
        body: HomeContent(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  const HomeContent({Key? key}) : super(key: key);

  List<Widget> _getListData() {
    List<Widget> list = [];
    for (var i = 0; i < 20; i++) {
      list.add(Container(
        alignment: Alignment.center,
        child: Text(
          "这是第$i个条目",
          style: TextStyle(color: Colors.white, fontSize: 20),
        ),
        color: Colors.blue,
        height: 500,
      ));
    }
    return list;
  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
    //水平子元素之间的距离
        crossAxisSpacing: 20,
      //垂直子元素之间的距离
        mainAxisSpacing: 20,
        padding: EdgeInsets.all(10),
        crossAxisCount: 3,
        //内部设置单个条目宽高无效,可以改变宽高比例达到目的,
        childAspectRatio: 0.7,
        children: _getListData());
  }
}


Flutter列表组件(ListView,GrideView)_第7张图片

// ignore_for_file: prefer_const_constructors, prefer_collection_literals, deprecated_member_use, unused_local_variable, must_be_immutable

import 'package:flutter/material.dart';
import 'res/listData.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Demo'),
        ),
        body: HomeContent(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  const HomeContent({Key? key}) : super(key: key);

  List<Widget> _getListData() {
    var tempList = listData.map((value) {
      return Container(
        child: Column(
          children: <Widget>[
            Image.network(value["imageUrl"]),
            SizedBox(height: 12),
            Text(value["title"],
                textAlign: TextAlign.center,
                 style: TextStyle(fontSize: 20)
            ),
          ],
        ),
        decoration: BoxDecoration(    
            border: Border.all(
                color: Color.fromRGBO(230, 230, 230, 0.9), 
                width: 1.0),
                borderRadius: const BorderRadius.all(
                Radius.circular(15),
              )
                ),
      );
    });
    return tempList.toList();
  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
        padding: EdgeInsets.all(20),
        crossAxisCount: 2,
        crossAxisSpacing: 20,
        mainAxisSpacing: 20,
        childAspectRatio: 0.7,
        children: _getListData());
  }
}

Flutter列表组件(ListView,GrideView)_第8张图片

GrideView.builder遍历数据生成列表

// ignore_for_file: prefer_const_constructors, prefer_collection_literals, deprecated_member_use, unused_local_variable, must_be_immutable

import 'package:flutter/material.dart';
import 'res/listData.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Demo'),
        ),
        body: HomeContent(),
      ),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  const HomeContent({Key? key}) : super(key: key);

  Widget _getListData(context, index) {
    return Container(
      child: Column(
        children: <Widget>[
          Image.network(listData[index]["imageUrl"]),
          SizedBox(height: 12),
          Text(listData[index]["title"],
              textAlign: TextAlign.center, style: TextStyle(fontSize: 20)),
        ],
      ),
      decoration: BoxDecoration(
          border: Border.all(
              color: Color.fromRGBO(230, 230, 230, 0.9), width: 1.0)),
    );
  }

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      itemCount: listData.length,
      itemBuilder: _getListData,
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          //横轴元素个数
          crossAxisCount: 2, //纵轴间距
          mainAxisSpacing: 20.0, //横轴间距
          crossAxisSpacing: 10.0, //子组件宽高长度比例
          childAspectRatio: 1.0),
    );
  }
}

Flutter列表组件(ListView,GrideView)_第9张图片

你可能感兴趣的:(Flutter,flutter,android,dart)