【问题标题】:Flutter Hero Animation with TextField Error带有 TextField 错误的 Flutter Hero 动画
【发布时间】:2021-10-07 02:53:49
【问题描述】:

我想在我的一个屏幕中创建搜索功能。概念如下:我有一个标记搜索功能的 TextField。当我点击它时,我不想在 TextField 中输入内容,而是导航到 AppBar 内带有 TextField 的另一个屏幕,用户应该在其中进行搜索。 (类似于 Android 上的 Facebook 应用程序)。但我想通过从一个 TextField 到另一个 TextField 的 Hero 过渡来做到这一点。

这是一些代码:

class Screen1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Padding(
          padding: EdgeInsets.symmetric(horizontal: 15),
          child: Hero(
            tag: "search_text_field",
            child: TextField(
              decoration: InputDecoration(
                prefixIcon: Icon(
                  Icons.search,
                  size: 24,
                ),
                hintText: "Search",
              ),
              focusNode: AlwaysDisabledFocusNode(),
              onTap: () {
                Navigator.pushNamed(context, SEARCH_ROUTE);
              },
            ),
          ),
        ),
        ...moreWidgets
      ],
    );
  }
}


class SearchScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: Icon(
            Icons.arrow_back,
            color: AppTheme.grey,
          ),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
        backgroundColor: Colors.white,
        title: Hero(
          tag: "search_text_field",
          child: TextField(
            decoration: InputDecoration(
              hintText: "Search",
            ),
          ),
        ),
      ),
    );
  }
}

注意FirstScreen 是另一个屏幕中的一个小部件,它有一个脚手架小部件。所以两个 Screen 都已经有了一个 Scaffold Widget。

英雄过渡有效。但在过渡期间,我收到以下错误:

The following assertion was thrown building TextField(decoration: InputDecoration(hintText: "Search")), dirty, dependencies: [MediaQuery, UnmanagedRestorationScope], state: _TextFieldState#6cb29):
No Material widget found.

TextField widgets require a Material widget ancestor.
In material design, most widgets are conceptually "printed" on a sheet of material. In Flutter's material library, that material is represented by the Material widget. It is the Material widget that renders ink splashes, for instance. Because of this, many material library widgets require that there be a Material widget in the tree above them.

To introduce a Material widget, you can either directly include one, or use a widget that contains Material itself, such as a Card, Dialog, Drawer, or Scaffold.

The specific widget that could not find a Material ancestor was: TextField
  decoration: InputDecoration(hintText: "Search"))
  dirty
  dependencies: [MediaQuery, UnmanagedRestorationScope]
  state: _TextFieldState#6cb29
The ancestors of this widget were: 
  : Theme
    ThemeData#56afb
  : MaterialApp
    state: _MaterialAppState#ef29b
  : MyApp
  : BlocProvider<AuthCubit>
  ...
The relevant error-causing widget was: 
  TextField file:///Users/user/StudioProjects/project/lib/search_screen.dart:22:18
When the exception was thrown, this was the stack: 
#0      debugCheckHasMaterial.<anonymous closure> (package:flutter/src/material/debug.dart:27:7)
#1      debugCheckHasMaterial (package:flutter/src/material/debug.dart:48:4)
#2      _TextFieldState.build (package:flutter/src/material/text_field.dart:1116:12)
#3      StatefulElement.build (package:flutter/src/widgets/framework.dart:4691:27)
#4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4574:15)
...

我想我错了:在英雄转换期间,TextField 小部件未包装在材质小部件中,这会导致错误(但我不确定)。

那我该怎么办呢?

提前非常感谢:)

【问题讨论】:

    标签: flutter


    【解决方案1】:

    用Material 包裹你的TextField。

    完整代码。

    import 'package:flutter/material.dart';
    
    class Screen1 extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Padding(
                padding: EdgeInsets.symmetric(horizontal: 15),
                child: Hero(
                  tag: "search_text_field",
                  child: Material(
                    child: TextField(
                      decoration: InputDecoration(
                        prefixIcon: Icon(
                          Icons.search,
                          size: 24,
                        ),
                        hintText: "Search",
                      ),
                      // focusNode: AlwaysDisabledFocusNode(),
                      onTap: () {
                        Navigator.of(context).push(MaterialPageRoute(
                          builder: (context) => SearchScreen(),
                        ));
                      },
                    ),
                  ),
                ),
              ),
              // ...moreWidgets
            ],
          ),
        );
      }
    }
    
    class SearchScreen extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            leading: IconButton(
              icon: Icon(
                Icons.arrow_back,
                color: Colors.grey,
              ),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
            backgroundColor: Colors.white,
            title: Hero(
              tag: "search_text_field",
              child: Material(
                child: TextField(
                  decoration: InputDecoration(
                    hintText: "Search",
                  ),
                ),
              ),
            ),
          ),
        );
      }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-04
      • 1970-01-01
      • 2020-10-24
      • 2019-12-16
      • 1970-01-01
      • 2019-08-01
      • 2020-03-02
      • 2020-10-28
      相关资源
      最近更新 更多