[障害対応]Provider/Consumerをbottom直下で使用していた時の障害(The argument type ‘Consumer‘ can’t be assigned to the parameter type ‘PreferredSizeWidget?’

目次 index【閲覧時間3分】 click !!>>

1.事象

Provider利用時に、Consumerを2か所に配置( bottom と body の直後)していたところ、
bottom 直後の Consumer のところで、エラーが発生しました(下図)。

(エラー内容)

The argument type ‘Consumer‘ can’t be assigned to the parameter type ‘PreferredSizeWidget?’

(修正前):
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Editable and Scrollable Tabs with Add Tab'),
        bottom: Consumer<TabManager>(
          builder: (context, tabManager, child) {
            return TabBar(
              controller: tabManager.tabController,
              isScrollable: true,
              tabs: [
                ...tabManager.tabTitles.map(
                  (title) => Tab(
                    child: SizedBox(
                      width: 120,
                      child: TextField(
                        controller: TextEditingController(text: title),
                        onSubmitted: (newTitle) {
                          int index = tabManager.tabTitles.indexOf(title);
                          tabManager.updateTabTitle(index, newTitle);
                        },
                        decoration: const InputDecoration(border: InputBorder.none),
                      ),
                    ),
                  ),
                ),
                const Tab(icon: Icon(Icons.add)),
              ],
            );
          },
        ),
      ),
      body: Consumer<TabManager>(
        builder: (context, tabManager, child) {
          return TabBarView(

2.修正内容

Consumerウィジェットを PreferredSize ウィジェットでラップして、AppBarの bottom プロパティに渡しました。
PreferredSize ウィジェットは、PreferredSizeWidget を期待する場所で使用されることを想定しており、内部にあるConsumer ウィジェットを適切に扱うことができます。

(修正後):
 @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Editable and Scrollable Tabs with Add Tab'),
        bottom: PreferredSize(
          preferredSize: const Size.fromHeight(48.0),
          child: Consumer<TabManager>(
            builder: (context, tabManager, child) {
              return TabBar(
                controller: tabManager.tabController,
                isScrollable: true,
                tabs: [
                  ...tabManager.tabTitles.map(
                    (title) => Tab(
                      child: SizedBox(
                        width: 120,
                        child: TextField(
                          controller: TextEditingController(text: title),
                          onSubmitted: (newTitle) {
                            int index = tabManager.tabTitles.indexOf(title);
                            tabManager.updateTabTitle(index, newTitle);
                          },
                          decoration: const InputDecoration(border: InputBorder.none),
                        ),
                      ),
                    ),
                  ),
                  const Tab(icon: Icon(Icons.add)),
                ],
              );
            },
          ),
        ),
      ),
      body: Consumer<TabManager>(
        builder: (context, tabManager, child) {
          return TabBarView(

3.まとめ

provider の Consumer は、bottom 直下配置時とbody直下配置時では扱い方が異なる、という事例でした。

コメントを残す