Flutter学习案例分享-计数器小案例

Flutter框架基础概念简介

Widget,Element 和 RenderObject 类型

  • 虽然Widget是开发人员创建和管理的,但Flutter框架会并行构建和管理另外两棵树,称为元素树和渲染对象树。这三种树用于构建用户画面(UI)并决定何时刷新他们。

  • StatelessWidget这种widget不需要可变状态。最适合用于描述UI中永不可改的部分。

  • StatefulWidget这种widget具有可变状态,一般在开发者需要控制widget的生命周期或动态内容时使用。StatefulWidget本身是不可变的,但它的状态是可变的,并且由一个单独的State对象表示。

项目创建

  • 一个小计数器案例(结构很简单,小伙伴们可以根据个人的习惯来创建文件目录)。

  • 在lib目录下创建一个counter目录,在该目录下创建一个counter_app_body文件。

  • 首先修改main文件代码
void main() {
  runApp(const EnhancedCounterApp());
}

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: CounterAppBody(),
    );
  }
}
  • 创建新目录和文件
  • 在counter_app_body创建一个有状态的Widget.

  • 然后在counter目录下在添加一个widget目录,并在该目录下创建app_title文件来显示程序的标题.

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

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(120),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(
            Icons.remove,
            color: Colors.redAccent,
          ),
          Text(
            '计数器App',
            style: TextStyle(
              color: Colors.black,
              fontSize: 20,
            ),
          ),
          Icon(
            Icons.add,
            color: Colors.lightGreen,
          )
        ],
      ),
    );
  }
}
  • widget目录下创建文件
  • 在widget目录下创建history_widget文件,它用来显示计数器下方的滚动列表。这样做可以提高可读性和UI部分的分离。

  • 在有状态Widget需要初始化或是需要更新时需要使用State类下的一些方法来控制。本程序中使用到了didUpdateWidget来更新添加计数时更新列表的状态。

  • 当我们点击+时才会更新列表,当点击-时,只减少计数器的值,列表不变。

import 'package:flutter/material.dart';

class HistoryWidget extends StatefulWidget {
  //计数器历史
  final List increasesHistory;
  const HistoryWidget({super.key, required this.increasesHistory});

  @override
  State createState() => _HistoryWidgetState();
}

class _HistoryWidgetState extends State {
  //滚动视图控制器
  final controller = ScrollController();

  //缓存列表
  late ListView list = buildList();
  //构建列表
  ListView buildList() {
    return ListView.separated(
      key: const Key('历史列表'),
      controller: controller,
      scrollDirection: Axis.horizontal,
      itemCount: widget.increasesHistory.length,
      itemBuilder: (_, index) {
        return Card(
          elevation: 4,
          shadowColor: Colors.blueAccent,
          child: SizedBox(
            width: 40,
            height: 40,
            child: Center(
              child: Text('${widget.increasesHistory[index]}'),
            ),
          ),
        );
      },
      separatorBuilder: (_, __) => const SizedBox(width: 10),
    );
  }

  @override
  void didUpdateWidget(covariant HistoryWidget oldWidget) {
    super.didUpdateWidget(oldWidget);

    if (widget.increasesHistory.length != oldWidget.increasesHistory.length) {
      // 更新列表
      list = buildList();

      // 移动到尾部
      controller.animateTo(
        controller.position.maxScrollExtent + 50 + 10,
        duration: const Duration(milliseconds: 400),
        curve: Curves.ease,
      );
    }
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        // 标题
        const Text(
          '计数器列表',
          style: TextStyle(
            fontSize: 20,
          ),
        ),

        // 实际的列表
        Flexible(
          child: Padding(
            padding: const EdgeInsets.symmetric(
              horizontal: 40,
              vertical: 15,
            ),
            child: SizedBox(
              height: 40,
              child: list,
            ),
          ),
        ),
      ],
    );
  }
}
更新主页面
  • 下面来到counter_app_body文件,完成CounterAppBody有状态类的代码

  • 我们需要在State类中添加计数器变量、列表历史和增加和减少计数器的方法

    import 'package:counter_app/counter/widgets/app_title.dart';
    import 'package:counter_app/counter/widgets/history_widget.dart';
    import 'package:flutter/material.dart';
    
    class CounterAppBody extends StatefulWidget {
      const CounterAppBody({super.key});
    
      @override
      State createState() => _CounterAppBodyState();
    }
    
    class _CounterAppBodyState extends State {
      //计数器变量
      int count = 0;
      // 跟踪当按下 '+1' 时计数器状态的变化
      List incrementHistory = [];
      //将计数器增加1
      void increment() {
        setState(() {
          count++;
          incrementHistory = List.from(incrementHistory)..add(count);
        });
      }
    
      //将计数器减少1
      void decrement() {
        setState(() {
          count--;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const AppTitle(),
                //添加两个按钮和计数器文本
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.blueAccent,
                      ),
                      onPressed: decrement,
                      child: const Text(
                        '-',
                        style: TextStyle(fontSize: 30),
                      ),
                    ),
                    const SizedBox(width: 16),
                    ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.blueAccent,
                      ),
                      onPressed: increment,
                      child: const Text('+', style: TextStyle(fontSize: 30)),
                    ),
                  ],
                ),
                HistoryWidget(
                  increasesHistory: incrementHistory,
                ),
              ],
            ),
          ),
        );
      }
    }

    在IOS下运行程序

你可能感兴趣的:(Flutter案例学习,flutter,学习)