我试图添加一个BottomModelSheet在交易列表中添加新的交易,我遵循,这就是我得到的错误,我在这里错过了什么?
这是我的main.dart文件
import 'package:expense_tracker/widgets/transaction_list.dart';
import './widgets/transaction_list.dart';
import 'package:flutter/material.dart';
import './widgets/new_transaction.dart';
import './models/transaction.dart';
void main() => runApp(MyHomePage());
class MyHomePage extends StatefulWidget {
// String titleInput;
// String amountInput;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final titleController = TextEditingController();
final amountController = TextEditingController();
final List<Transaction> _userTransactions = [
Transaction(
id: 't1',
title: 'New Shoes',
amount: 1000,
date: DateTime.now(),
),
Transaction(
id: 't2',
title: 'USB Cable',
amount: 600,
date: DateTime.now(),
),
];
void _addNewTransaction(String txTitle, double txAmount) {
final newTX = Transaction(
title: txTitle,
amount: txAmount,
date: DateTime.now(),
id: DateTime.now().toString());
setState(() {
_userTransactions.add(newTX);
});
}
void _startAddNewTransaction(BuildContext ctx) {
showModalBottomSheet(context: ctx,builder: (bCtx) {
return NewTransaction(_addNewTransaction);
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter App'),
actions: [
IconButton(
icon: Icon(Icons.add),
onPressed: () => _startAddNewTransaction(context),
),
],
),
body: SingleChildScrollView(
child: Column(
// mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: double.infinity,
child: Card(
color: Colors.blue,
child: Text('CHART'),
elevation: 10,
),
),
TransactionList(_userTransactions),
]),
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => _startAddNewTransaction(context),
),
),
);
}
}
单击appBar上的图标和底部的floatActionButton时,将显示相同的BottomModalSheet,但它们都不起作用。
答案 0 :(得分:0)
您要传递给BuildContext
方法的_startAddNewTransaction
是_MyHomePageState
的方法。由于_MyHomePageState
包含MaterialApp
(并非相反),因此它的BuildContext
对此一无所知。
您有2个选择:
使用Builder
小部件包装调用该方法的小部件,小部件的BuildContext
将了解MaterialApp
创建一个新的小部件(例如MyHomePageContent
),并将其传递给物料应用的body:
参数。
第一个选项是快速修复,第二个选项是更好的解决方法。
将项目分成多个文件是一个好主意,例如:
main.dart
void main() => runApp(MyApp());
my_app.dart
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
my_home_page.dart
class MyHomePage extends StatefulWidget {
// String titleInput;
// String amountInput;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final titleController = TextEditingController();
final amountController = TextEditingController();
final List<Transaction> _userTransactions = [
Transaction(
id: 't1',
title: 'New Shoes',
amount: 1000,
date: DateTime.now(),
),
Transaction(
id: 't2',
title: 'USB Cable',
amount: 600,
date: DateTime.now(),
),
];
void _addNewTransaction(String txTitle, double txAmount) {
final newTX = Transaction(
title: txTitle,
amount: txAmount,
date: DateTime.now(),
id: DateTime.now().toString());
setState(() {
_userTransactions.add(newTX);
});
}
void _startAddNewTransaction(BuildContext ctx) {
showModalBottomSheet(
context: ctx,
builder: (bCtx) {
return NewTransaction(_addNewTransaction);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter App'),
actions: [
IconButton(
icon: Icon(Icons.add),
onPressed: () => _startAddNewTransaction(context),
),
],
),
body: SingleChildScrollView(
child: Column(
// mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: double.infinity,
child: Card(
color: Colors.blue,
child: Text('CHART'),
elevation: 10,
),
),
TransactionList(_userTransactions),
]),
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => _startAddNewTransaction(context),
),
);
}
}