• flutte: 可滚动列表


    Column 组件默认占用全部可用高度,Row 组件默认占用全部可用宽度。

    ColumnRow默认不具有滚动功能,当屏幕尺寸不能容纳组件时,将产生溢出:

    在这里插入图片描述

    增加滚动功能方法

    方法1,使用 SingleChildScrollView wrap body 相关组件

    vs code: 选定需要增加滚动功能的 Column 或者 Row, 鼠标左键 -> refactor -> Wrap with widget,然后将名称 widget改为 SingleChildScrollView:

    在这里插入图片描述

    SingleChildScrollView 实现列表的滚动功能,不再产生溢出:

    body: SingleChildScrollView(
              child: Column(
                // mainAxisAlignment: MainAxisAlignment.spaceAround,
                // crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  Container(
                    width: double.infinity,
                    child: Card(
                      color: Colors.blue,
                      child: Text('CHART'),
                      elevation: 5,
                    ),
                  ),
                  UserTransactions(),
                ],
              ),
            ));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    方法2,使用 SingleChildScrollView wrap子组件

    取消方法1中增加的 SingleChildScrollView ,将要增加滚动功能的组件wrap 在 Container 组件里,设置 Container 的size,然后将 Column wrap 在 SingleChildScrollView 里:

    @override
      Widget build(BuildContext context) {
        return Container(
          height: 300,  // 如果此 heigt足够大,将产生溢出。
          child: SingleChildScrollView(
            child: Column(
              children: transactions.map((tx) {
                return Card(
                  child: Row(
                    children: <Widget>[
                      Container(
                        margin: EdgeInsets.symmetric(
                          vertical: 10,
                          horizontal: 10,
                        ),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述
    为了取消用户输入时出现的溢出,在 body 里增加 SingleChildScrollView,同方法1:

    body: SingleChildScrollView(
              child: Column(
                // mainAxisAlignment: MainAxisAlignment.spaceAround,
                // crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  Container(
                    width: double.infinity,
                    child: Card(
                      color: Colors.blue,
                      child: Text('CHART'),
                      elevation: 5,
                    ),
                  ),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    方法3,使用 ListView 组件

    使用 ListView 取代 SingleChildScrollView + Column,因为可滚动的列表十分常见,因此使用 ListView 作为捷径,代码更简洁。

    将代码中的 Column 直接替换成 ListView

    Widget build(BuildContext context) {
        return Container(
          height: 300,
          child: ListView(
            children: transactions.map((tx) {
              return Card(
                child: Row(
                  children: <Widget>[
                    Container(
                      margin: EdgeInsets.symmetric(
                        vertical: 10,
                        horizontal: 10,
                      ),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    ListView 组件有两种构造函数:

    1. ListView(children: [])
    2. ListView.builder()

    当列表的items 足够多,必定有一部分 items 不可见,二者之间的区别是,ListView.builder() 进行了优化,使用懒惰加载的方式,只加载可见的 items,而 ListView(children: []) 则可见不可见的 items 全部加载,这将影响 performance。

    所以,当列表很大或长度未知时,选择ListView.builder()

    使用 ListView(children: [])

    import 'package:flutter/material.dart';
    import 'package:intl/intl.dart';
    import '../models/transaction.dart';
    
    class TransactionList extends StatelessWidget {
      final List<Transaction> transactions;
      TransactionList(this.transactions);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          height: 300,
          child: ListView(
            children: transactions.map((tx) {
              return Card(
                child: Row(
                  children: <Widget>[
                    Container(
                      margin: EdgeInsets.symmetric(
                        vertical: 10,
                        horizontal: 10,
                      ),
                      decoration: BoxDecoration(
                        border: Border.all(
                          color: Colors.purple,
                          width: 2,
                        ),
                      ),
                      padding: EdgeInsets.all(10),
                      child: Text('\$${tx.amount}',
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 20,
                            color: Colors.purple,
                          )),
                    ),
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          tx.title,
                          style:
                              TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
                        ),
                        Text(
                          // tx.date.toString(),
                          // DateFormat().format(tx.date),
                          // DateFormat('yyyy-MM-dd').format(tx.date),
                          // DateFormat('yyyy/MM/dd').format(tx.date),
                          DateFormat.yMMMd().format(tx.date),
                          style: TextStyle(
                            color: Colors.grey,
                          ),
                        )
                      ],
                    )
                  ],
                ),
              );
            }).toList(),
          ),
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    使用 ListView.builder()

    需要提供两个参数,itemBuilder 函数,以及 列表长度 itemCount,上面的代码修改得到如下代码:

    import 'package:flutter/material.dart';
    import 'package:intl/intl.dart';
    import '../models/transaction.dart';
    
    class TransactionList extends StatelessWidget {
      final List<Transaction> transactions;
      TransactionList(this.transactions);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          height: 300,
          child: ListView.builder(
            itemBuilder: ((ctx, index) {
              return Card(
                child: Row(
                  children: <Widget>[
                    Container(
                      margin: EdgeInsets.symmetric(
                        vertical: 10,
                        horizontal: 10,
                      ),
                      decoration: BoxDecoration(
                        border: Border.all(
                          color: Colors.purple,
                          width: 2,
                        ),
                      ),
                      padding: EdgeInsets.all(10),
                      child: Text('\$${transactions[index].amount}',
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 20,
                            color: Colors.purple,
                          )),
                    ),
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          transactions[index].title,
                          style:
                              TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
                        ),
                        Text(
                          DateFormat.yMMMd().format(transactions[index].date),
                          style: TextStyle(
                            color: Colors.grey,
                          ),
                        )
                      ],
                    )
                  ],
                ),
              );
            }),
            itemCount: transactions.length,
          ),
        );
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
  • 相关阅读:
    Kafka与Spring Boot等应用框架的集成及消息驱动模型
    互联网Java工程师面试题·Java 面试篇·第五弹
    Kubernetes 集群管理:Kurator or Kubespray
    san.js源码解读之工具(util)篇——extend函数
    windows下使用FFmpeg开源库进行视频编解码完整步聚
    《asp.net core 3 高级编程(第8版)》学习笔记 01
    Spring Boot中发送邮件时,如何让发件人显示别名
    events_statements_summary_by_digest 未正常记录分类sql
    FreeRTOS学习笔记——SysTick中断
    error: unable to read askpass response from
  • 原文地址:https://blog.csdn.net/ftell/article/details/126287676