我正在尝试根据 TextField 小部件的空/非空状态动态显示小部件。下面是我写的代码。但即使我在税收百分比的文本字段中输入文本,代码也不会动态创建小部件。这是出乎意料的。在这里,我也不确定我们是否可以按照我在代码中所做的方式
late
分配Provider。
我尝试过的。我尝试将 Provider 类中的布尔变量
isEmptyTaxPercentage
声明为 static
,并在 TaxPercentage TextField 的 onChanged 中使用静态访问方法进行设置。但是,由于没有调用 notificationListeners() 函数,这也许也没有按预期工作:预期的小部件没有动态显示。
更新01:修复了以下代码。现在它按预期工作了。剩下的唯一问题是在 State 类中将提供者声明为
late MyTaxProvider myTaxProvider
是否有效且良好实践?
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<MyTaxProvider>(
create: (context) => MyTaxProvider(),
),
],
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Provider Demo'),
);
}
}
class MyTaxProvider with ChangeNotifier {
bool isEmptyTaxPercentage = true;
void setTaxPercentageEmptynessState(bool value) {
isEmptyTaxPercentage = value;
notifyListeners();
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late final TextEditingController costController;
late final TextEditingController taxPercentageController;
late final TextEditingController taxAmountController;
late MyTaxProvider myTaxProvider;
@override
void initState() {
super.initState();
costController = TextEditingController();
taxPercentageController = TextEditingController();
taxAmountController = TextEditingController();
myTaxProvider = Provider.of<MyTaxProvider>(context, listen: false);
}
@override
void dispose() {
costController.dispose();
taxPercentageController.dispose();
taxAmountController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Column(
children: [
Row(
children: [
const Expanded(
child: Text("Cost:"),
),
Expanded(
child: TextField(
controller: costController,
),
),
],
),
Row(
children: [
const Expanded(
child: Text("Tax precentage (%):"),
),
Expanded(
child: TextField(
controller: taxPercentageController,
onChanged: (value) {
if (value.isEmpty) {
myTaxProvider.setTaxPercentageEmptynessState(true);
} else {
myTaxProvider.setTaxPercentageEmptynessState(false);
}
},
),
),
],
),
Consumer<MyTaxProvider>(
builder: (context, provider, child) {
if (provider.isEmptyTaxPercentage) {
return Container();
} else {
return Row(
children: [
const Expanded(
child: Text("Tax Amount:"),
),
Expanded(
child: TextField(
controller: taxAmountController,
),
),
],
);
}
},
),
const Text("Other widget(s)."),
],
),
),
);
}
}
不推荐将提供程序声明为较晚您可能应该在构建方法中像下面这样使用它
final myTaxProvider = Provider.of<MyTaxProvider>(context, listen: false);
这样您的代码会更加清晰,并避免有关后期初始化的潜在错误。