Flutter ListView 教程 – 做一个体重追踪APP 1(FLUTTER LISTVIEW TUTORIAL – WEIGHTTRACKER 1)

本文来自于我自己学习Flutter时所学习的教程的中文翻译,原文链接https://marcinszalek.pl/flutter/flutter-listview/

英语水平有限,内容未必准确

在Flutter里创建一个ListView

在这篇文章里,我将展示创建一个能动态插入数据的基本的ListView。让我们开始吧。

1. 一个简单的ListView

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  HomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _HomePageState createState() => new _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<String> strings = new List();

  void _addWeightSave() {
    setState(() {
      strings.add("new string");
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new ListView(
        children:
        strings.map((String string) {
          return new Row(
            children: [
              new Text(string)
            ],
          );
        }).toList(),
      ),

      floatingActionButton: new FloatingActionButton(
        onPressed: _addWeightSave,
        tooltip: 'Add new weight entry',
        child: new Icon(Icons.add),
      ),
    );
  }
}

从这段代码能想像到我构建的是一个最简单的ListView。

ListView 部件(widget)是列表的主容器,它装载着所有的内容,但是我们只需要关注它的children属性。

我们需要给ListView.children提供一个部件列表(list of Widgets)用于显示。所以我们用经过初始化后的装着String的List来生成每一行的容器,每一行的容器内只装着一个字符串。

这样我们就得到了下面这样的一个列表。

现在让我们做一些不是Hello World的事情。

2. 复杂的行布局

2.1 创建model

class WeightSave {
  DateTime dateTime;
  double weight;

  WeightSave(this.dateTime, this.weight);
}

2.2 创建布局

# pubspace.yaml
dependencies:
  flutter:
    sdk: flutter
  intl: ^0.15.7
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:weight_tracker/model/WeightSave.dart';

class WeightListItem extends StatelessWidget {
  final WeightSave weightSave;
  final double weightDifference;

  WeightListItem(this.weightSave, this.weightDifference);

  @override
  Widget build(BuildContext context) {
    return new Padding(
      padding: new EdgeInsets.all(16.0),
      child: new Row(children: [
        new Expanded(
            child: new Column(children: [
              new Text(
                new DateFormat.yMMMMd().format(weightSave.dateTime),
                textScaleFactor: 0.9,
                textAlign: TextAlign.left,
              ),
              new Text(
                new DateFormat.EEEE().format(weightSave.dateTime),
                textScaleFactor: 0.8,
                textAlign: TextAlign.right,
                style: new TextStyle(
                  color: Colors.grey,
                ),
              ),
            ], crossAxisAlignment: CrossAxisAlignment.start)),
        new Expanded(
            child: new Text(
              weightSave.weight.toString(),
              textScaleFactor: 2.0,
              textAlign: TextAlign.center,
            )),
        new Expanded(
            child: new Text(
              weightDifference.toString(),
              textScaleFactor: 1.6,
              textAlign: TextAlign.right,
            )),
      ]),
    );
  }
}

根布局是一个padding,这是为了让布局间不轻易接触而做的一个基础的包装。

padding的子节点(child)是一个Row容器,包含了3个子节点(children),Row部件(widget)内部的所有部件会水平排列。

为了让Row内部3个部件每个都占1/3的空间,所以3个部件都使用了Expanded来包装。

左边的列是一个Column部件。Column跟Row类似,不过是纵向排列。在Column.children里我们放置了两个Text用于显示model对象的时间和星期。

中间和右边的列都是一个简单的Text部件,中间列设计为显示保存的重量,右边的列用于显示跟前一项重量的差值。

2.3 把这些都组装起来

用我们的新的WeightListItem布局对象替换掉前面每行的布局(记得添加import)

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:weight_tracker/WeightListItem.dart';
import 'package:weight_tracker/model/WeightSave.dart';

class HomePage extends StatefulWidget {
  HomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _HomePageState createState() => new _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<WeightSave> weightSaves = new List();

  void _addWeightSave() {
    setState(() {
      weightSaves.add(new WeightSave(
          new DateTime.now(), new Random().nextInt(100).toDouble()));
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new ListView(
        children: weightSaves.map((WeightSave weightSave) {
          //calculating difference
          double difference = weightSaves.first == weightSave
              ? 0.0
              : weightSave.weight -
                  weightSaves[weightSaves.indexOf(weightSave) - 1].weight;
          return new WeightListItem(weightSave, difference);
        }).toList(),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _addWeightSave,
        tooltip: 'Add new weight entry',
        child: new Icon(Icons.add),
      ),
    );
  }
}

这样就完成了!

我希望你会喜欢这篇文章,如果有什么意见和建议希望留言反馈!

你可以在这里找到整个项目。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值