Flutter学习日记之初识ListView组件

Posted Android_小黑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter学习日记之初识ListView组件相关的知识,希望对你有一定的参考价值。

​本文地址:https://blog.csdn.net/qq_40785165/article/details/117265919,转载需附上此地址

大家好,我是小黑,一个还没秃头的程序员~~~

没有谁的幸运,凭空而来,只有当你足够努力,你才会足够幸运!

今天分享的内容是Flutter的ListView&GridView组件,用来绘制页面中的列表,源码地址:https://gitee.com/fjjxxy/flutter-study.git,效果如下:
在这里插入图片描述
Demo各页面说明

标签索引说明
标签1ListTile的使用
标签2使用任意的widget构建列表
标签3水平列表
标签4使用builder构造列表以及分割线的设置
标签5GridView的使用

注意:Demo中使用的是本地Json数据,获取自玩Android的开放Api,后面学习了访问网络数据之后再来更新文章!

(一) 使用ListTile构造ListView

ListTile是内置的一个组件,组件内已经具备基本的组件结构,包括前后图片,一级文字,二级文字等,效果如demo中的标签一

参数说明
leading前图片
title一级文字
subtitle二级文字
trailing后图片
contentPadding类似于组件内的padding,默认只有左右各16间距
onTap点击事件
onLongPress长按事件
horizontalTitleGap中间文字与前后图片的水平间距,默认16

这里只列举用过的几个参数,还有其他的参数没去尝试过,大家感兴趣的话欢迎下载源码体验!

代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_study/data/Data.dart';
import 'package:flutter_study/utils/Toast.dart';

class ListViewTab1 extends StatefulWidget {
  @override
  _ListViewTab1State createState() => _ListViewTab1State();
}

class _ListViewTab1State extends State<ListViewTab1> {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: _getData(context),
    );
  }
}

List<Widget> _getData(context) {
  List<Widget> widgetList = list.map((value) {
    return ListTile(
      horizontalTitleGap: 10,//前图片与标题,标题与后图片的水平间距,默认16
      contentPadding: EdgeInsets.symmetric(horizontal: 16.0),//类似于组件内的padding,默认只有水平的16间距
      onTap: () {
        Toast.toast(context, msg: "${value["name"]}", position: "bottom");
      },
      dense: true,
      title: Text("${value["name"]}"),
      subtitle: Text("${value["order"]}"),
      leading: Icon(Icons.menu),
    );
  }).toList();
  return widgetList;
}

(二)使用任意的widget数组构造列表

使用ListTile只能局限于自身的布局结构,不利于自定义,ListView的children参数是一个Widget数组,所以可以把ListTile替换成任意的组件,效果如Demo中的标签二,代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_study/data/Data.dart';

class ListViewTab2 extends StatefulWidget {
  @override
  _ListViewTab2State createState() => _ListViewTab2State();
}

class _ListViewTab2State extends State<ListViewTab2> {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: _getData(),
    );
  }
}
List<Widget> _getData() {
  List<Widget> widgetList = list.map((value) {
   if(value["id"]%2==0){
     return Container(
       height: 40,
       alignment: Alignment.center,
       decoration: BoxDecoration(borderRadius: BorderRadius.only(topRight: Radius.circular(10),bottomRight: Radius.circular(10)),border: Border.all(color: Colors.black)),
       margin: EdgeInsets.fromLTRB(0, 10, 40, 10),
       child: Text("${value["name"]}"),
     );
   }else{
     return Container(
       height: 40,
       alignment: Alignment.center,
       decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(10),bottomLeft: Radius.circular(10)),border: Border.all(color: Colors.black)),
       margin: EdgeInsets.fromLTRB(40, 10, 0, 10),
       child: Text("${value["name"]}"),
     );
   }
  }).toList();
  return widgetList;

(三)水平列表

使用scrollDirection参数即可定义列表滑动方向

说明
Axis.horizontal水平列表
Axis.vertical垂直列表

效果如Demo中的标签三,代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_study/data/Data.dart';

class ListViewTab3 extends StatefulWidget {
  @override
  _ListViewTab3State createState() => _ListViewTab3State();
}

class _ListViewTab3State extends State<ListViewTab3> {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 100,
      child:  ListView(
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        children: _getData(),
      ),
    );
  }
}

List<Widget> _getData() {
  List<Widget> widgetList = list.map((e){
    return buildContainer(e["name"]);
  }).toList();
  return widgetList;
}

Container buildContainer(String text) {
  return Container(
    alignment: Alignment.center,
    margin: EdgeInsets.all(10),
    decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(10)),border: Border.all(color: Colors.black)),
    width: 100,
    child: ListTile(
      title: Text(text,textAlign: TextAlign.center,),
    ),
  );
}

(四)builder的使用

ListView还可以使用ListView.separated或者ListView.builder进行构建列表,如果你需要定义分割线,那你可以使用前者进行绘制列表,反之可以使用后者

参数说明
scrollDirection列表的方向
reverse是否倒序
controller滑动监听
physics设置滑动的效果以及是否可以滑动
shrinkWrap多用于ListView被嵌套时引起的高度问题,设置true使得ListView不限高度
padding一整个列表的内间距(不是子项的内间距)
itemBuilder对应一个函数,参数类型是BuildContext和int,根据索引绘制子项组件
separatorBuilder对应一个函数,参数类型是BuildContext和int,根据索引绘制分割线组件
itemCount列表长度

效果如Demo中的标签四,代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_study/data/Data.dart';

class ListViewTab4 extends StatefulWidget {
  @override
  _ListViewTab4State createState() => _ListViewTab4State();
}

class _ListViewTab4State extends State<ListViewTab4> {
  @override
  Widget build(BuildContext context) {
    return ListView.separated(
      separatorBuilder: (context,index){
        return Container(
          height: 1,
          color: Colors.grey,
        );

      },
      itemCount: list.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text("${list[index]["name"]}"),
        );
      },
    );
  }
}

(五)GridView的使用

GridView可以使用两种方式创建

  • GridView.count()
  • GridView.builder()

首先介绍第一种写法,GridView.count()中的参数如下:

参数说明
crossAxisSpacing水平元素的间距
mainAxisSpacing垂直距离的间距
crossAxisCount一列几个元素

还有些参数和listView一样,比如内间距、滑动方向等,这里就不介绍了
效果如Demo中的标签5,代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_study/data/Data.dart';

class GridViewTab extends StatefulWidget {
  @override
  _GridViewTabState createState() => _GridViewTabState();
}

class _GridViewTabState extends State<GridViewTab> {
  @override
  Widget build(BuildContext context) {
    return GridView.count(
      crossAxisCount: 3,///三列
      crossAxisSpacing: 10,//水平元素的间距
      mainAxisSpacing: 10,//垂直距离的间距
      padding: EdgeInsets.all(20),
      children: _getData(),
    );
  }
}

List _getData() {
  List widgetList = list.map((e) {
    return Container(
      height: 40,
      alignment: Alignment.center,
      color: Colors.red,
      child: Text("${e["name"]}",style: TextStyle(color: Colors.white),),
    );
  }).toList();
  return widgetList;
}

接下来介绍第二种方式GridView.builder(),这个和ListView中的builder差不多,只不过crossAxisSpacing、crossAxisSpacing、mainAxisSpacing这几个参数无法在builder中使用,必须要用SliverGridDelegateWithFixedCrossAxisCount组件才能传入这些参数,代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_study/data/Data.dart';

class GridViewTab extends StatefulWidget {
  @override
  _GridViewTabState createState() => _GridViewTabState();
}

class _GridViewTabState extends State<GridViewTab> {
  @override
  Widget build(BuildContext context) {
    return GridView.builder(
    	//现在这个是必传的参数了
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3, ///三列
          crossAxisSpacing: 10, //水平元素的间距
          mainAxisSpacing: 10,//垂直距离的间距
        ), 
        itemCount: list.length,
        itemBuilder: (context, index) {
          return Container(
            height: 40,
            alignment: Alignment.center,
            color: Colors.red,
            child: Text(
              "${list[index]["name"]}",
              style: TextStyle(color: Colors.white),
            ),
          );
        });
  }
}

到此为止,Flutter中ListView以及GridView使用的内容就介绍完毕了,多写才能熟能生巧,感兴趣的小伙伴可以下载源码看一下,希望大家可以点个star,支持一下小白的flutter学习经历,最后,希望喜欢我文章的朋友们可以帮忙点赞、收藏、评论,也可以关注一下,如果有问题可以在评论区提出,后面我会持续更新Flutter的学习记录,与大家分享,谢谢大家的支持与阅读!

以上是关于Flutter学习日记之初识ListView组件的主要内容,如果未能解决你的问题,请参考以下文章

Flutter学习日记之实现上拉加载&下拉刷新的Listview

Flutter学习日记之实现上拉加载&下拉刷新的Listview

Flutter学习日记之Image组件详解

Flutter学习日记之底部导航栏BottomNavigationBar组件的使用

Flutter学习日记之Chip标签组件的使用

Flutter学习日记之表单组件TextField文本框的使用