Home > database >  No Material widget found with Hero & Ink.image widget
No Material widget found with Hero & Ink.image widget

Time:10-18

I am using Ink.image widget because I want to splash/ripple effect on image but if I use it with Hero widget its gives error that Material widget ancestors not found which is not true because Scaffold is a Material widget but I also try to explicitly add Material widget below InkWell widget but nothing happens it's still not detecting it.

import 'package:flutter/material.dart';

void main() => runApp(const App());

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.light().copyWith(
        splashColor: Colors.amber.withAlpha(150),
        highlightColor: Colors.transparent,
      ),
      home: const Home(),
    );
  }
}

class Home extends StatelessWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Home"),
      ),
      body: Center(
        child: InkWell(
          onTap: () {
            Navigator.of(context).push(
              MaterialPageRoute(
                builder: (context) => const Detail(),
              ),
            );
          },
          child: SizedBox(
            width: 100,
            height: 100,
            child: Hero(
              tag: "tag",
              child: Ink.image(
                image: const NetworkImage(
                  "https://storage.googleapis.com/cms-storage-bucket/0dbfcc7a59cd1cf16282.png",
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class Detail extends StatelessWidget {
  const Detail({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Detail"),
      ),
      body: Hero(
        tag: "tag",
        child: Ink.image(
          image: const NetworkImage(
            "https://storage.googleapis.com/cms-storage-bucket/0dbfcc7a59cd1cf16282.png",
          ),
        ),
      ),
    );
  }
}

I want this behaviour but without errors

enter image description here

Restarted application in 2,605ms.
I/flutter (13108): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (13108): The following assertion was thrown building Ink(bg: BoxDecoration(image:
I/flutter (13108): DecorationImage(NetworkImage("https://storage.googleapis.com/cms-storage-bucket/0dbfcc7a59cd1cf16282.png",
I/flutter (13108): scale: 1.0), Alignment.center, scale 1.0, opacity 1.0, FilterQuality.low)), dirty, state:
I/flutter (13108): _InkState#82f44):
I/flutter (13108): No Material widget found.
I/flutter (13108): Ink widgets require a Material widget ancestor.
I/flutter (13108): In Material Design, most widgets are conceptually "printed" on a sheet of material. In Flutter's
I/flutter (13108): material library, that material is represented by the Material widget. It is the Material widget
I/flutter (13108): that renders ink splashes, for instance. Because of this, many material library widgets require that
I/flutter (13108): there be a Material widget in the tree above them.
I/flutter (13108): To introduce a Material widget, you can either directly include one, or use a widget that contains
I/flutter (13108): Material itself, such as a Card, Dialog, Drawer, or Scaffold.
I/flutter (13108): The specific widget that could not find a Material ancestor was:
I/flutter (13108):   Ink
I/flutter (13108): The ancestors of this widget were:
I/flutter (13108):   ...
I/flutter (13108):   MediaQuery
I/flutter (13108):   AnimatedBuilder
I/flutter (13108):   FadeTransition
I/flutter (13108):   IgnorePointer
I/flutter (13108):   Positioned
I/flutter (13108):   ...
I/flutter (13108):
I/flutter (13108): The relevant error-causing widget was:
I/flutter (13108):   Ink Ink:file:///C:/Users/Burhan/Desktop/test/lib/main.dart:67:22
I/flutter (13108):
I/flutter (13108): When the exception was thrown, this was the stack:
I/flutter (13108): #0      debugCheckHasMaterial.<anonymous closure> (package:flutter/src/material/debug.dart:29:7)
I/flutter (13108): #1      debugCheckHasMaterial (package:flutter/src/material/debug.dart:50:4)
I/flutter (13108): #2      _InkState.build (package:flutter/src/material/ink_decoration.dart:300:12)
I/flutter (13108): #3      StatefulElement.build (package:flutter/src/widgets/framework.dart:4992:27)
I/flutter (13108): #4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4878:15)
I/flutter (13108): #5      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5050:11)
I/flutter (13108): #6      Element.rebuild (package:flutter/src/widgets/framework.dart:4604:5)
I/flutter (13108): #7      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4859:5)
I/flutter (13108): #8      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5041:11)
I/flutter (13108): #9      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4853:5)
I/flutter (13108): ...     Normal element mounting (57 frames)
I/flutter (13108): #66     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3863:16)
I/flutter (13108): #67     MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6435:36)
I/flutter (13108): #68     Element.updateChild (package:flutter/src/widgets/framework.dart:3592:18)
I/flutter (13108): #69     RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:5964:32)
I/flutter (13108): #70     MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6460:17)
I/flutter (13108): #71     Element.updateChild (package:flutter/src/widgets/framework.dart:3570:15)
I/flutter (13108): #72     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4904:16)
I/flutter (13108): #73     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5050:11)
I/flutter (13108): #74     Element.rebuild (package:flutter/src/widgets/framework.dart:4604:5)
I/flutter (13108): #75     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2667:19)
I/flutter (13108): #76     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:882:21)
I/flutter (13108): #77     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:378:5)
I/flutter (13108): #78     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1175:15)
I/flutter (13108): #79     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1104:9)
I/flutter (13108): #80     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1015:5)
I/flutter (13108): #81     _invoke (dart:ui/hooks.dart:148:13)
I/flutter (13108): #82     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)
I/flutter (13108): #83     _drawFrame (dart:ui/hooks.dart:115:31)
I/flutter (13108):
I/flutter (13108): ════════════════════════════════════════════════════════════════════════════════════════════════════

CodePudding user response:

Try this:

Wrap it with Material as it must have a Material widget as an ancestor. The Material widget is where the ink reactions are actually painted. This matches the material design premise wherein the Material is what is actually reacting to touches by spreading ink.

Widget build(BuildContext context) {     
return Hero(       
child: Material(child: Ink.image())}

CodePudding user response:

void main() => runApp(const App());

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Home(),
    );
  }
}

class Home extends StatelessWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Home"),
      ),
      body: Center(
        child: InkWell(
          onTap: () {
            Navigator.of(context).push(
              MaterialPageRoute(
                builder: (context) => const Detail(),
              ),
            );
          },
          child: SizedBox(
            width: 100,
            child: Hero(
              tag: "tag",
              child: Material(
                child: Ink.image(
                  height: 100,
                  image: Image.network(
                    "https://storage.googleapis.com/cms-storage-bucket/0dbfcc7a59cd1cf16282.png",
                  ).image,
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class Detail extends StatelessWidget {
  const Detail({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Detail"),
      ),
      body: Hero(
        tag: "tag",
        child: Material(
          child: Ink.image(
              image: Image.network(
            "https://storage.googleapis.com/cms-storage-bucket/0dbfcc7a59cd1cf16282.png",
          ).image),
        ),
      ),
    );
  }
}

So from this answer here, what I observe is that a widget wrapped with the Hero widget is not necessarily wrapped with a Material widget, so you have to rewrap the child widget of a Hero widget with a Material widget again.

CodePudding user response:

Try this one:

Stack( 
      children: [
        Positioned.fill(
          child: Container(
            decoration: const BoxDecoration(color: Colors.blue),
            child: Image.network(
              "https://storage.googleapis.com/cms-storage- bucket/0dbfcc7a59cd1cf16282.png"),
        ),
      ),
      Positioned.fill(
        child: Material(
          color: Colors.transparent,
          child: InkWell(onTap: () {}),
        ),
      ),
])

CodePudding user response:

Try below code, just wrap your Ink.image() with material widget

your Home widget:

class Home extends StatelessWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Home"),
      ),
      body: Center(
        child: InkWell(
          onTap: () {
            Navigator.of(context).push(
              MaterialPageRoute(
                builder: (context) => const Detail(),
              ),
            );
          },
          child: SizedBox(
            width: 100,
            child: Hero(
              tag: "tag",
              child: Material(
                child: Ink.image(
                  height: 100,
                  image: Image.network(
                    "https://storage.googleapis.com/cms-storage-bucket/0dbfcc7a59cd1cf16282.png",
                  ).image,
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Your Detail widget:

class Detail extends StatelessWidget {
  const Detail({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Detail"),
      ),
      body: Hero(
        tag: "tag",
        child: Material(
          child: Ink.image(
              image: Image.network(
            "https://storage.googleapis.com/cms-storage-bucket/0dbfcc7a59cd1cf16282.png",
          ).image),
        ),
      ),
    );
  }
}
  • Related