flutter - 当我在颤振中使用 PreferredSizeWidget 时,CupertinoNavigationBar 出现了一些错误?
问题描述
**main.dart**
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import './widgets/transaction_list.dart';
import './widgets/new_transaction.dart';
import './widgets/chart.dart';
import './models/transaction.dart';
void main() {
// WidgetsFlutterBinding.ensureInitialized();
// SystemChrome.setPreferredOrientations([
// DeviceOrientation.portraitUp,
// DeviceOrientation.portraitDown,
// ]);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Personal Expenses',
home: MyHomePage(),
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.purple,
accentColor: Colors.amber,
fontFamily: "Quicksand",
textTheme: ThemeData.light().textTheme.copyWith(
headline6: TextStyle(
fontFamily: "OpenSans",
fontWeight: FontWeight.bold,
fontSize: 18,
),
button: TextStyle(color: Colors.white),
),
appBarTheme: AppBarTheme(
titleTextStyle: TextStyle(
fontFamily: "OpenSans",
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
);
}
}
class MyHomePage extends StatefulWidget {
// late String titleInput;
// late String amountInput;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<Transaction> _userTransactions = [];
List<Transaction> get _recentTransaction {
return _userTransactions.where((tx) {
return tx.date.isAfter(
DateTime.now().subtract(
Duration(days: 7),
),
);
}).toList();
}
bool _showChart = false;
void _addNewTransaction(
String txTitle, double txAmount, DateTime chosenDate) {
final newTx = Transaction(
title: txTitle,
amount: txAmount,
id: DateTime.now().toString(),
date: chosenDate,
);
setState(() {
_userTransactions.add(newTx);
});
}
void _startAddNewTransaction(BuildContext ctx) {
showModalBottomSheet(
context: ctx,
builder: (_) {
return GestureDetector(
onTap: () {},
child: NewTransaction(_addNewTransaction),
behavior: HitTestBehavior.opaque,
);
},
);
}
void _deleteTransaction(String id) {
setState(() {
_userTransactions.removeWhere((tx) {
return tx.id == id;
});
});
}
@override
Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context);
final isLandScape = mediaQuery.orientation == Orientation.landscape;
final PreferredSizeWidget appBar = Platform.isIOS
? CupertinoNavigationBar(
middle: Text(
"Personal Expenses",
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
GestureDetector(
child: Icon(CupertinoIcons.add),
onTap: () => _startAddNewTransaction(context),
)
],
),
)
: AppBar(
title: Text(
'Personal Expenses',
),
actions: <Widget>[
IconButton(
onPressed: () => _startAddNewTransaction(context),
icon: Icon(Icons.add),
)
],
);
final txListWidget = Container(
height: (mediaQuery.size.height -
appBar.preferredSize.height -
mediaQuery.padding.top) *
0.7,
child: TransactionList(_userTransactions, _deleteTransaction),
);
final pageBody = SingleChildScrollView(
child: Column(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
if (isLandScape)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Show chart"),
Switch.adaptive(
activeColor: Theme.of(context).accentColor,
value: _showChart,
onChanged: (value) {
setState(() {
_showChart = value;
});
},
),
],
),
if (!isLandScape)
Container(
height: (mediaQuery.size.height -
appBar.preferredSize.height -
mediaQuery.padding.top) *
0.3,
child: Chart(_recentTransaction),
),
if (!isLandScape) txListWidget,
if (isLandScape)
_showChart
? Container(
height: (mediaQuery.size.height -
appBar.preferredSize.height -
mediaQuery.padding.top) *
0.7,
child: Chart(_recentTransaction),
)
: txListWidget,
],
),
);
return Platform.isIOS
? CupertinoPageScaffold(
child: pageBody,
navigationBar: appBar,
)
: Scaffold(
appBar: appBar,
body: pageBody,
floatingActionButtonLocation:
FloatingActionButtonLocation.centerFloat,
floatingActionButton: Platform.isIOS
? Container()
: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => _startAddNewTransaction(context),
),
);
}
}
当我使用最终的 PreferredSizeWidget appBar = Platforn.isISO 时?CupertinoNavigationBar() : AppBar();
它向我显示了此错误以及 CupertinoPageScaffold(child: (), navigationBar: appBar) 中的错误。
代码中显示的错误是:“Widget”类型的值不能分配给“PreferredSizeWidget”类型的变量。尝试更改变量的类型,或将右侧类型转换为“PreferredSizeWidget”。
我该如何解决这个错误?
解决方案
我建议您为自己创建一个单独的 AppbarTop Widget。这样做的基础是在下面的代码片段中,添加您自己的逻辑并将其分配给appBar
您的Scaffold
.
import 'package:flutter/material.dart';
class AppbarTop extends StatelessWidget implements PreferredSizeWidget {
const AppbarTop();
@override
Widget build(BuildContext context) {
return Platform.isIOS ? CupertinoNavigationBar() : AppBar();
}
@override
Size get preferredSize => Size.fromHeight(AppBar().preferredSize.height);
}
推荐阅读
- php - 使用 PDO 在准备好的语句中传递日期 sql 类型
- android - 您上传的 APK 未使用具有相同密钥库的上传证书签名
- python - 在 Python 中附加数据框
- python - 如何在不使用numpy的情况下在python中的矩阵中创建附近数字之和的矩阵
- java - Java 和 C 是否以相同的方式表示 UTF char 字节?
- android - 即使在第一次加载表单时未选择任何内容,如何禁用 ionic 3 单选按钮中的验证消息?
- wpf - 这些名称在 WPF 应用程序项目中是否应该一致?
- python - 保存和检索模型名称
- python-3.x - 通过 API 访问受组织限制的 Google 表格
- asp.net - 未在 WCF 服务请求标头中获取 SoapAction 属性