«Виджет материала не найден». Анимация изображения героя между маршрутами

Flutter Newb: У меня есть сетка кнопок с изображениями на экране меню. При нажатии кнопки он анимируется в «ведущий» элемент панели приложений нового представления. Это работает, как я и ожидал. Все идет нормально...

Когда я использую Navigator.pop() во втором представлении, я получаю сообщение об ошибке «Нет виджета материала»... Конкретный виджет, который не смог найти предка материала: _InkResponseStateWidget... (хотя экран меню снова появляется, как и ожидалось

      /// ...
class MenuScreen extends StatelessWidget {
  const MenuScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Menu'),
      ),
      body: Center(
        child: GridView.count(
          crossAxisCount: 3,
          children: const [
            MenuButton('clients'),
    //...and so on

///...
class MenuButton extends StatelessWidget {
  final String indexStr;

  const MenuButton(this.indexStr, {Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Hero(
      child: InkWell(
        child: Ink.image(
          image: AssetImage('assets/images/$indexStr.png'),
          fit: BoxFit.cover,
        ),
        onTap: () => Navigator.pushNamed(context, '/' + indexStr),
        highlightColor: Colors.blue.withOpacity(0.5),
        splashColor: Colors.blue.withOpacity(0.9),
        borderRadius: BorderRadius.circular(100),
      ),
      tag: indexStr,
    );
  }
}

PS. Я тоже не могу сказать, что полностью понимаю весь контекст и ключевые вещи :-)

Код второго экрана

      import 'package:flutter/material.dart';

class ClientsScreen extends StatelessWidget {
  const ClientsScreen({Key? key}) : super(key: key);
  final indexStr = 'clients';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: Material(
          child: Hero(
            child: Image.asset('../assets/images/$indexStr.png'),
            tag: indexStr,
          ),
        ),
        title: const Text('Clients.'),
      ),
      body: Center(child: Text('Test')),
      floatingActionButton: FloatingActionButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: const Text('Back')),
    );
  }
}

Я предполагаю, что упускаю что-то очевидное, но не могу понять, что это может быть...

Обновление: и корневое приложение main.dart с картой маршрутов:

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Named Routes',
      theme: ThemeData(scaffoldBackgroundColor: Colors.white),
      initialRoute: '/',
      routes: {
        '/': (context) => const MenuScreen(),
        '/clients': (context) => const ClientsScreen(),
        '/checkin': (context) => const CheckinScreen(),
             },
    );
  }
}

1 ответ

Как уже отмечалось в комментариях, виджет необходим для переноса InkWell.

Причина:

Виджет InkWell должен иметь виджет Material в качестве предка. Виджет «Материал» — это место, где на самом деле рисуются чернильные реакции. Это соответствует предпосылке материального дизайна, согласно которой материал — это то, что на самом деле реагирует на прикосновения, распространяя чернила.

https://api.flutter.dev/flutter/material/InkWell-class.html

Эффекты рукописного ввода: Материал показывает эффекты рукописного ввода, реализованные InkFeatures, такими как InkSplash и InkHighlight, под его дочерними элементами.

https://api.flutter.dev/flutter/material/Material-class.html

Виджет отображает эффекты рукописного ввода, такие как InkSplashа также InkHighlightсоответствующих детей. Виджеты, уже реализующие эту функциональность, Scaffold, Cardи т.д. Именно поэтому один из них нужен как предок, а если нет, Materialнужно.

Другие вопросы по тегам