学习Flutter的第四天(组件2)

2023-04-22  本文已影响0人  囧rg

组件1:MaterialApp、Container、Text、Image、Icon
组件2:ListView、GridView
组件3:Padding、Row 、Column、Stack、Align、Positioned
组件4:AspectRatio、Row 、Button
组件5:Wrap、StatelessWidget 、StatefulWidget、Dialog、PageView、TextField

3.6 ListView

名称 功能
scrollDirection Axis.horizontal 横向,Axis.vertical 纵向
reverse 反向,元素从下面开始,往上排
children 子元素

ListView 纵向的时候,内部的Container的宽度设置不生效

ListView 横向的时候,内部的Container的高度设置不生效

3.6.1 ListTitle

ListTileFlutter 给我们准备好的widget 提供非常常见的构造和定义方式,包括文字,icon,点击事件,一般是能够满足基本需求,但是就不能自己定义了

this.leading,              // item 前置图标
this.title,                // item 标题
this.subtitle,             // item 副标题
this.trailing,             // item 后置图标
this.isThreeLine = false,  // item 是否三行显示
this.dense,                // item 直观感受是整体大小
this.contentPadding,       // item 内容内边距
this.enabled = true
this.onTap,                // item onTap 点击事件
this.onLongPress,          // item onLongPress 长按事件
this.selected = false,     // item 是否选中状态

代码如下:

class MyList extends StatelessWidget {
  const MyList({super.key});

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: const <Widget>[
        ListTile(
          leading: Icon(Icons.home),
          title: Text("我是列表"),
        ),
        Divider(),
        ListTile(
          subtitle: Text("我是副标题"),
          title: Text("我是列表"),
        ),
        Divider(),
        ListTile(
          trailing: Icon(Icons.person),
          title: Text("我是列表"),
        ),
        Divider(),
      ],
    );
  }
}

3.6.2 动态列表

class MyList extends StatelessWidget {
  const MyList({super.key});

  List<Widget> _listData() {
    List<Widget> list = [];
    for (var i = 0; i < 20; i++) {
      list.add(ListTile(
        title: Text("data $i"),
      ));
    }
    return list;
  }

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

也可以把数据单独放一个文件中 data.dart

List dtListData = [
  {"name": "zhangsan", "age": 19},
  {"name": "李四", "age": 20},
  {"name": "找份", "age": 18},
  {"name": "没事", "age": 31},
  {"name": "四五年", "age": 12},
  {"name": "奥", "age": 3},
  {"name": "没事", "age": 9},
  {"name": "饿哦", "age": 19},
];

引入文件

import 'res/data.dart';

class MyList extends StatelessWidget {
  const MyList({super.key});

  List<Widget> _listData() {
    
    // 第一种写法
    List<Widget> list = [];
    for (var i = 0; i < dtListData.length; i++) {
      var data = dtListData[i];
      String name = data["name"];
      int age = data["age"];
      list.add(ListTile(
        title: Text("姓名 $name"),
        subtitle: Text("年龄 $age"),
      ));
    }
    return list;
    
    // 第二种写法
    var list = dtListData.map((e) {
      String name = e["name"];
      int age = e["age"];
      return ListTile(
        title: Text("姓名 $name"),
        subtitle: Text("年龄 $age"),
      );
    });
    return list.toList();
  }

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

2.6.3 builder

builder 顾名思义 构造 可以非常方便的构建我们自己定义的child布局,所以在Flutter中非常的常用

//设置滑动方向 Axis.horizontal 水平  默认 Axis.vertical 垂直
scrollDirection: Axis.vertical,
//内间距
padding: EdgeInsets.all(10.0),
//是否倒序显示 默认正序 false  倒序true
reverse: false,
//false,如果内容不足,则用户无法滚动 而如果[primary]为true,它们总是可以尝试滚动。
primary: true,
//确定每一个item的高度 会让item加载更加高效
itemExtent: 50.0,
//内容适配
shrinkWrap: true,
//item 数量
itemCount: list.length,
//滑动类型设置
physics: new ClampingScrollPhysics(),
//cacheExtent  设置预加载的区域 
cacheExtent: 30.0, 
//滑动监听
//controller ,

使用builder时,itemCount 和 itemBuilder 必须有

class MyBuildList extends StatelessWidget {
  List<String> list = [];

  // ignore: empty_constructor_bodies
  MyBuildList({Key? key}) : super(key: key) {
    for (var i = 0; i < 20; i++) {
      list.add("value $i");
    }
  }

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

3.7 GridView

可以通过 GridView.count 实现网格布局,控制一行有多少个子组件

可以通过 GridView.extent 实现网格布局,控制一行每个组件的长度,长度超出一行,就放下一行。

名称 功能
scrollDirection 滚动方向,Axis.horizontal 横向,Axis.vertical 纵向
reverse 组件反向排序,元素从下面开始,往上排
children 子元素
padding 内边距
crossAxisSpacing 子组件之间水平距离
mainAxisSpacing 子组件之间垂直距离
crossAxisCount 用在 GridView.count 中,一行中子组件数量
maxCrossAxisExtent 用在 GridView.extent 中,每个子组件的固定的最大长度
childAspectRatio 设置宽高比例

3.7.1 GridView.count 和 GridView.extent

// GridView.count 实现网格布局
class MyGridViewCount extends StatelessWidget {
  const MyGridViewCount({super.key});

  @override
  Widget build(BuildContext context) {
    return GridView.count(
      // 一行有多少个元素
      crossAxisCount: 3,
      children: const [
        Icon(Icons.home),
        Icon(Icons.home_max),
        Icon(Icons.shop),
        Icon(Icons.percent),
        Icon(Icons.person),
        Icon(Icons.adb_outlined),
        Icon(Icons.assessment),
        Icon(Icons.deblur),
        Icon(Icons.sick),
      ],
    );
  }
}

// GridView.extent 实现网格布局
class MyGridViewExtent extends StatelessWidget {
  const MyGridViewExtent({super.key});

  @override
  Widget build(BuildContext context) {
    return GridView.extent(
      // 每个元素的长度是固定的40
      maxCrossAxisExtent: 100,
      children: const [
        Icon(Icons.home),
        Icon(Icons.home_max),
        Icon(Icons.shop),
        Icon(Icons.percent),
        Icon(Icons.person),
        Icon(Icons.adb_outlined),
        Icon(Icons.assessment),
        Icon(Icons.deblur),
        Icon(Icons.sick),
      ],
    );
  }
}

3.7.2 GridView.builder

class MyGridViewBuilder extends StatelessWidget {
  const MyGridViewBuilder({super.key});

  Widget _initWidget(context, index) {
    return Container(
      decoration: BoxDecoration(border: Border.all(color: Colors.redAccent)),
      child: Text("$index"),
    );
  }

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
        itemCount: 10, // 循环次数
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3, // 一行显示多少个元素
            crossAxisSpacing: 10, // 子组件 水平间距
            mainAxisSpacing: 10, // 子组件 垂直间距
            childAspectRatio: 1), // 宽高比
        itemBuilder: _initWidget
        // (content, index) {}
        );
  }
}

注:

使用 SliverGridDelegateWithFixedCrossAxisCount ,使用属性 crossAxisCount

使用 SliverGridDelegateWithMaxCrossAxisExtent , 使用属性 maxCrossAxisExtent

上一篇 下一篇

猜你喜欢

热点阅读