实现 PreferredSizeWidget 以用作 Appbar

Posted

技术标签:

【中文标题】实现 PreferredSizeWidget 以用作 Appbar【英文标题】:Implementing PreferredSizeWidget For Use As Appbar 【发布时间】:2018-10-02 09:26:48 【问题描述】:

我正在尝试构建一个可用于识别列表视图中的两列的组件。我希望能够将此标题栏实现为 Scaffold 中的 appbar,以便我可以在 Scaffold 的主体部分中实现 ListView。我想这样做是因为我想在我的应用程序中多次使用这种模式,并且不希望每次都实现粗略的标题栏。

因为 AppBar 组件只需要实现 PreferredSizeWidget,我认为这应该很简单:

import 'package:flutter/material.dart';

class ListTitleBar extends StatefulWidget implements PreferredSizeWidget 

  final String _left;
  final String _right;

  ListTitleBar(this._left, this._right);

  @override
  State<StatefulWidget> createState() => new ListTitleBarState(_left, _right);

  @override
  Size get preferredSize 
    new Size.fromHeight(20.0);
  



class ListTitleBarState extends State<ListTitleBar> 

  String _leftTitle;
  String _rightTitle;

  ListTitleBarState(this._leftTitle, this._rightTitle);

  @override
  Widget build(BuildContext context) 

return new Container(

  decoration: new BoxDecoration(
    color: Colors.redAccent,
    border: new Border.all(color: Colors.black),
  ),

  child: new Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: <Widget>[

      ///Left Column Title
      new Column(
        children: <Widget>[
          new Container(
            color: Colors.redAccent,
            padding: const EdgeInsets.all(10.0),
            child: new Text(_leftTitle,
              style: new TextStyle(
                  color: Colors.white,
                  fontSize: 18.0
              ),
            ),
          )
        ],
      ),

      ///Right Column Title
      new Column(
        children: <Widget>[
          new Container(
            color: Colors.redAccent,
            padding: const EdgeInsets.all(10.0),
            child: new Text(_rightTitle,
              style: new TextStyle(
                  color: Colors.white,
                  fontSize: 18.0
              ),
            ),
          )
        ],
      ),

    ],
  ),
);



@override
void initState() 
  super.initState();


 @override
 void dispose() 
   super.dispose();
 


我的问题是关于成功实施 PreferredSizeWidget 或实现我的目标还需要什么。现在我得到以下堆栈跟踪,这似乎表明我忽略了实现的几个方面:

══╡小部件库╞════════════════════════════════ ═════════════════════ I/flutter(9130):在构建 Scaffold(脏,状态: I/flutter(9130):ScaffoldState#7c75d(代码:跟踪 1 个代码)): I/flutter (9130):在 null 上调用了 getter 'height'。 我/颤振(9130):接收器:空 I/flutter(9130):尝试调用:高度 我/颤振(9130): I/flutter (9130):当异常被抛出时,这是堆栈: I/flutter (9130):#0 Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:46:5) I/flutter (9130): #1 ScaffoldState.build (package:flutter/src/material/scaffold.dart:1447:57) I/flutter (9130): #2 StatefulElement.build (package:flutter/src/widgets/framework.dart:3713:27) I/flutter (9130): #3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3625:15) I/flutter (9130): #4 Element.rebuild (package:flutter/src/widgets/framework.dart:3478:5) I/flutter (9130): #5 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3605:5) I/flutter (9130): #6 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3752:11) I/flutter (9130): #7 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3600:5) I/flutter (9130): #8 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2890:14) I/flutter (9130): #9 Element.updateChild (package:flutter/src/widgets/framework.dart:2693:12) I/flutter (9130): #10 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3636:16)

【问题讨论】:

基本上你是想创建一个有标题和列表的组件,这就是你的意思吗? 不,我想创建一个可以分配给 Scaffold Widget 中的 appBar 字段的组件。我会在 Scaffold 的 body 字段中实现 ListView。 【参考方案1】:

正如他所说的@Giraldi,你忘记了 return 声明,所以你可以这样做,你也可以这样做。

class ListTitleBar extends StatefulWidget implements PreferredSizeWidget 

  ListTitleBar(Key key) : preferredSize = Size.fromHeight(50.0), super(key: key);
  
  @override
  final Size preferredSize;

  @override
  State<StatefulWidget> createState() => new ListTitleBarState();


【讨论】:

【参考方案2】:

我认为您忘记了 preferredSize 中的 return 声明。应该是这样的:

Size get preferredSize return new Size.fromHeight(20.0);

【讨论】:

或者写成:@override Size get preferredSize =&gt; Size.fromHeight(20.0); 箭头语法不需要return 语句。

以上是关于实现 PreferredSizeWidget 以用作 Appbar的主要内容,如果未能解决你的问题,请参考以下文章

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

Riverpod - 如何在消费者中包装 PreferredSizeWidget

参数类型“Widget”不能分配给参数类型“PreferredSizeWidget?”。颤动中的appBar发生错误[重复]

如何优化 spark 函数以用零替换空值?

Flask--参考以用

C++ 格式化 int 数字以用点分隔千位