【问题标题】:A value of type 'Widget' can't be assigned to a variable of type 'PreferredSizeWidget'“Widget”类型的值不能分配给“PreferredSizeWidget”类型的变量
【发布时间】:2021-07-23 02:12:28
【问题描述】:

此程序中有 2 个错误已在上图中显示

Main.dart 文件

void main() {
 
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Personal Expenses ',
      theme: ThemeData(
        primarySwatch: Colors.green,
        accentColor: Colors.amber,
        //errorColor: Colors.red[700],
        fontFamily: 'Quicksand',
        textTheme: ThemeData.light().textTheme.copyWith(
            title: TextStyle(
              fontFamily: 'OpenSans',
              fontWeight: FontWeight.bold,
              fontSize: 18,
            ),
            button: TextStyle(color: Colors.amber)),
        appBarTheme: AppBarTheme(
          textTheme: ThemeData.light().textTheme.copyWith(
                title: TextStyle(
                  fontFamily: 'OpenSans',
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                ),
              ),
        ),
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
 
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List<Transaction> _userTransactions = [
   
  ];
  bool _showChart = false;
  List<Transaction> get _recentTransactions {
    return _userTransactions.where((tx) {
      return tx.date.isAfter(
        DateTime.now().subtract(
          Duration(days: 7),
        ),
      );
    }).toList();
  }

  void _addNewTransaction(
      String txTitle, double txAmount, DateTime chosenDate) {
    final newTx = Transaction(
      title: txTitle,
      amount: txAmount,
      date: chosenDate,
      id: DateTime.now().toString(),
    );

    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) => tx.id == id);
    });
  }

  @override
  Widget build(BuildContext context) {
    final mediaQuery = MediaQuery.of(context);
    final isLandscape = mediaQuery.orientation == Orientation.landscape;
    final PreferredSizeWidget appbar = Platform.isIOS 

“Widget”类型的值不能分配给“PreferredSizeWidget”类型的变量。

        ? 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 ',
              style: TextStyle(fontFamily: 'OpenSans'),
            ),
            actions: <Widget>[
              IconButton(
                icon: Icon(Icons.add),
                onPressed: () => _startAddNewTransaction(context),
              ),
            ],
          );
    final txListWidget = Container(
      height: (mediaQuery.size.height -
              appbar.preferredSize.height -
              mediaQuery.padding.top) *
          0.7,
      child: TransactionList(
        _userTransactions,
        _deleteTransaction,
      ),
    );
    final pageBody = SingleChildScrollView(
      child: Column(
        
        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: (val) {
                    setState(() {
                      _showChart = val;
                    });
                  },
                ),
              ],
            ),
         
        ],
      ),
    );

返回 Platform.isIOS ? CupertinoPageScaffold( 孩子:pageBody, 导航栏:应用栏,

参数类型“PreferredSizeWidget”不能分配给参数类型“ObstructingPreferredSizeWidget?”。

          )
        : Scaffold(
            .........,
                  ),
          );
  }
}

【问题讨论】:

  • 在提供代码示例时,请将整个文件包含在一个代码块中,以便更容易重现您的问题。您始终可以在代码中将错误添加为 cmets。

标签: flutter dart


【解决方案1】:

您的代码可以在 Flutter 的非 null 安全版本中运行。我不知道为什么 null 安全版本现在反对:

final PreferredSizeWidget appbar = Platform.isIOS ...

如果省略类型:

final appbar = Platform.isIOS ...

然后appbar 被解释为Widget 并在appbar.preferredSize 上给出错误。

您可以强制在运行时检查类型:

final dynamic appbar = Platform.isIOS ...

这适用于我使用我的 Android 设备进行测试。但是,我没有在 Apple 设备上进行过测试。

我创建了这个 flutter issue 来改变使用 null 安全版本的 Flutter 的行为。您可以订阅问题以获取更新通知。

编辑: Flutter 团队提出了 Dart issue 来解释新行为并建议使用:

final PreferredSizeWidget appbar = (Platform.isIOS ? CupertinoNavigationBar() : AppBar()) 
                                   as PreferredSizeWidget;

【讨论】:

  • 感谢您的回答。如果我在我要回答的其他问题中提到您,请不要误会我,我将确保发布的代码易于复制。再次感谢
  • 如果我根据您在编辑中提到的内容更改代码,我会收到此错误stackoverflow.com/questions/67395364/… 参数类型“PreferredSizeWidget”不能分配给参数类型“ObstructingPreferredSizeWidget?”
  • 以后使用appbar时可以向下转换,即navigationBar: appbar as ObstructingPreferredSizeWidget
【解决方案2】:

问题是,appBar 接受实现 PreferredSize 的小部件

和 CupertinoPageScaffold 接受 widget 的实现 ObstructingPreferredSizeWidget

所以不要确定appbar的数据类型

并让它在运行时确定

简单地把它变成这样

最终的 appBar = Platform.IOS ? CupertinoNavigationBar() : AppBar()

并在 CupertinoPageScaffold 中添加 CupertinoNavigationBar

并在 Scaffold 中添加 AppBar

【讨论】:

  • 这似乎不起作用,先生,如果我删除 PreferredSizeWidget 我得到另一个错误 The getter 'preferredSize' is not defined for the type 'Widget'.
猜你喜欢
  • 2021-08-23
  • 2021-11-11
  • 2023-01-20
  • 1970-01-01
  • 2020-11-25
  • 1970-01-01
  • 1970-01-01
  • 2021-12-13
  • 2018-04-19
相关资源
最近更新 更多