Flutter学习案例分享-计数器小案例
·
Flutter框架基础概念简介
Widget,Element 和 RenderObject 类型
-
虽然Widget是开发人员创建和管理的,但Flutter框架会并行构建和管理另外两棵树,称为元素树和渲染对象树。这三种树用于构建用户画面(UI)并决定何时刷新他们。
-
StatelessWidget这种widget不需要可变状态。最适合用于描述UI中永不可改的部分。
-
StatefulWidget这种widget具有可变状态,一般在开发者需要控制widget的生命周期或动态内容时使用。StatefulWidget本身是不可变的,但它的状态是可变的,并且由一个单独的State<T>对象表示。
项目创建
-
一个小计数器案例(结构很简单,小伙伴们可以根据个人的习惯来创建文件目录)。
-
在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<int> increasesHistory;
const HistoryWidget({super.key, required this.increasesHistory});
@override
State<HistoryWidget> createState() => _HistoryWidgetState();
}
class _HistoryWidgetState extends State<HistoryWidget> {
//滚动视图控制器
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<CounterAppBody> createState() => _CounterAppBodyState(); } class _CounterAppBodyState extends State<CounterAppBody> { //计数器变量 int count = 0; // 跟踪当按下 '+1' 时计数器状态的变化 List<int> incrementHistory = []; //将计数器增加1 void increment() { setState(() { count++; incrementHistory = List<int>.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下运行程序

更多推荐

所有评论(0)