动态的widget
创建一个动态的widget,通过点击按钮执行方法,使count+1,然后通过 text控件来进行显示。 创建StatefulWidget会为我们自动创建一个state的方法
class _CounterState extends State
在方法里我们可以进行操作,动态的去修改值
void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: Center(
//创建一个计时器对象,既然是动态的就要使用fulwidget
child: Counter(),
),
),
)
);
}
class Counter extends StatefulWidget {
const Counter({Key? key}) : super(key: key);
@override
State<Counter> createState() => _CounterState();
}
//创建StatefulWidget 会为我们自动创建一个状态对象
class _CounterState extends State<Counter> {
//定义一个int变量
int _counter = 0;
void _increment() {
//就是更改状态
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Row(
//是一个与当前方向一直的轴
mainAxisAlignment: MainAxisAlignment.center,
children: [
//创建一个按钮,来执行按压方法使数目+1
ElevatedButton(onPressed: _increment,
child: const Text('Increament')),
//眼红来限定孩子控件的大小
const SizedBox(
width: 16,
),
Text('Count:$_counter'),
],
);
}
}
两个静态的组件StatelessWidget如何做到刷新呢?
上一张原理图
- 父view将接口通过属性传给button
- button触发点击回调给父view
- 父viewsetstate触发build方法,更新text的值
上代码看看:
class CounterDisplay extends StatelessWidget {
const CounterDisplay({required this.count, super.key});
final int count;
@override
Widget build(BuildContext context) {
return Text('Count: $count');
}
}
class CounterIncrementor extends StatelessWidget {
const CounterIncrementor({required this.onPressed, super.key});
final VoidCallback onPressed;
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onPressed,
child: const Text('Increment'),
);
}
}
class Counter extends StatefulWidget {
const Counter({super.key});
@override
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _counter = 0;
void _increment() {
setState(() {
++_counter;
});
}
@override
Widget build(BuildContext context) {
print("每次点击按钮,会回调到父控件的方法,然后通过setstate去刷新控件 $_counter");
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CounterIncrementor(onPressed: _increment),
const SizedBox(width: 16),
CounterDisplay(count: _counter),
],
);
}
}
void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: Center(
child: Counter(),
),
),
),
);
}
创建一个listitem对象
import 'package:flutter/material.dart';
class Product {
const Product({required this.name});
final String name;
}
typedef CartChangeCallback = Function(
Product product,
bool inCart
);
void main() {
runApp(MaterialApp(
home: Scaffold(
body: Center(
child: ShoppingListItem(
product: const Product(name: 'Chips'),
inCart: false,
callback: (product, inCart) {},
),
),
),
));
}
class ShoppingListItem extends StatelessWidget {
ShoppingListItem({
required this.product,
required this.inCart,
required this.callback,
}) : super(key: ObjectKey(product));
final Product product;
final bool inCart;
final CartChangeCallback callback;
Color _getColor(BuildContext context) {
return inCart
? Colors.black54
: Theme.of(context).primaryColor;
}
TextStyle? _getTextStyle(BuildContext context) {
if (!inCart) return null;
return const TextStyle(
color: Colors.black54,
decoration: TextDecoration.lineThrough,
);
}
@override
Widget build(BuildContext context) {
return ListTile(
onTap: () {
callback(product,inCart);
},
//列表表头 颜色+文字
leading: CircleAvatar(
backgroundColor: _getColor(context),
child: Text(product.name[0]),
),
//列表的标题
title: Text(product.name,style:
_getTextStyle(context),),
);
}
}
使用listview展示多个ListTitle元素?
import 'package:flutter/material.dart';
class Product {
const Product({required this.name});
final String name;
}
typedef CartChangedCallback = Function(Product product, bool inCart);
class ShoppingListItem extends StatelessWidget {
ShoppingListItem({
required this.product,
required this.inCart,
required this.onCartChanged,
}) : super(key: ObjectKey(product));
final Product product;
final bool inCart;
final CartChangedCallback onCartChanged;
Color _getColor(BuildContext context) {
return inCart //
? Colors.black54
: Theme.of(context).primaryColor;
}
TextStyle? _getTextStyle(BuildContext context) {
if (!inCart) return null;
return const TextStyle(
color: Colors.black54,
decoration: TextDecoration.lineThrough,
);
}
@override
Widget build(BuildContext context) {
return ListTile(
//是一个点击函数
onTap: () {
print("被点击到了 $inCart");
onCartChanged(product, inCart);
},
leading: CircleAvatar(
backgroundColor: _getColor(context),
child: Text(product.name[0]),
),
title: Text(
product.name,
style: _getTextStyle(context),
),
);
}
}
class ShoppingList extends StatefulWidget {
const ShoppingList({required this.products, super.key});
final List<Product> products;
@override
State<ShoppingList> createState() => _ShoppingListState();
}
class _ShoppingListState extends State<ShoppingList> {
final _shoppingCart = <Product>{};
void _handleCartChanged(Product product, bool inCart) {
setState(() {
if (!inCart) {
_shoppingCart.add(product);
} else {
_shoppingCart.remove(product);
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Shopping List'),
),
body: ListView(
padding: const EdgeInsets.symmetric(vertical: 8.0),
children: widget.products.map((product) {
return ShoppingListItem(
product: product,
inCart: _shoppingCart.contains(product),
onCartChanged: _handleCartChanged,
);
}).toList(),
),
);
}
}
void main() {
runApp(const MaterialApp(
title: 'Shopping App',
home: ShoppingList(
products: [
Product(name: 'Eggs'),
Product(name: 'Flour'),
Product(name: 'Chocolate chips'),
],
),
));
}