InkWell zeigt keinen Welligkeitseffekt

96

Durch Antippen des Behälters wird der onTap()Handler ausgelöst, es wird jedoch kein Tintenspritzereffekt angezeigt.

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new InkWell(
          onTap: (){print("tapped");},
          child: new Container(
            width: 100.0,
            height: 100.0,
            color: Colors.orange,
          ),
        ),
      ),
    );
  }
}

Ich habe versucht, das InkWellInnere Containerauch zu setzen, aber vergebens.

J. Sarkar
quelle

Antworten:

152

Ich denke, dass das Hinzufügen von Farbe zum Behälter den Tinteneffekt überdeckt

https://docs.flutter.io/flutter/material/InkWell/InkWell.html

Dieser Code scheint zu funktionieren

  body: new Center(
    child: new Container(
      child: new Material(
        child: new InkWell(
          onTap: (){print("tapped");},
          child: new Container(
            width: 100.0,
            height: 100.0,
          ),
        ),
        color: Colors.transparent,
      ),
      color: Colors.orange,
    ),
  ),

Klicken Sie einfach auf das mittlere Quadrat.

Bearbeiten: Ich habe den Fehlerbericht gefunden. https://github.com/flutter/flutter/issues/3782

Dies ist tatsächlich wie erwartet, obwohl wir die Dokumente aktualisieren sollten, um es klarer zu machen.

Was passiert ist, dass die Materialspezifikation besagt, dass die Spritzer tatsächlich Tinte auf dem Material sind. Wenn wir also spritzen, lassen wir das Material-Widget buchstäblich spritzen. Wenn Sie etwas auf dem Material haben, spritzen wir darunter und Sie können es nicht sehen.

Ich wollte ein "MaterialImage" -Widget hinzufügen, das das Bild konzeptionell auch in das Material druckt, damit dann die Spritzer über dem Bild liegen. Wir könnten eine Materialdekoration haben, die etwas Ähnliches für eine Dekoration tut. Oder wir könnten Material selbst dekorieren lassen. Im Moment braucht es eine Farbe, aber wir könnten das auf eine ganze Dekoration ausweiten. Es ist jedoch nicht klar, ob es wirklich materialspezifikationskompatibel ist, ein Material mit einem Farbverlauf zu haben, daher bin ich mir nicht sicher, ob wir das tun sollen.

Kurzfristig können Sie, wenn Sie nur eine Problemumgehung benötigen, ein Material auf den Behälter legen, wobei das Material auf den Typ "Transparenz" eingestellt ist, und dann die Tinte gut darin platzieren.

--hixie

Update: Hixie hat letztes Jahr eine neue Ink-Lösung zusammengeführt. Die Tinte bietet eine bequeme Möglichkeit, über Bilder zu spritzen.

  testWidgets('Does the Ink widget render anything', (WidgetTester tester) async {
    await tester.pumpWidget(
      new Material(
        child: new Center(
          child: new Ink(
            color: Colors.blue,
            width: 200.0,
            height: 200.0,
            child: new InkWell(
              splashColor: Colors.green,
              onTap: () { },
            ),
          ),
        ),
      ),
    );


Material(
  color: Colors.grey[800],
  child: Center(
    child: Ink.image(
      image: AssetImage('cat.jpeg'),
      fit: BoxFit.cover,
      width: 300.0,
      height: 200.0,
      child: InkWell(
        onTap: () { /* ... */ },
        child: Align(
          alignment: Alignment.topLeft,
          child: Padding(
            padding: const EdgeInsets.all(10.0),
            child: Text('KITTEN', style: TextStyle(fontWeight: FontWeight.w900, color: Colors.white)),
          ),
        )
      ),
    ),
  ),
)

Bitte beachten Sie: Ich habe das neue Ink Widget nicht getestet. Ich habe den Code aus ink_paint_test.dart und den Dokumenten der Ink-Klasse kopiert

https://github.com/Hixie/flutter/blob/1f6531984984f52328e66c0cd500a8d517964564/packages/flutter/test/material/ink_paint_test.dart

https://github.com/flutter/flutter/pull/13900

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

user1462442
quelle
2
Sie können einfach die Farbe auf sich Materialselbst setzen und das weglassen Container.
Herohtar
1
Ich dachte mir, als CopsOnRoad seine Antwort veröffentlichte.
user1462442
1
@KoenVanLooveren Versuchen Sie CopsOnRoad Antwort. Ich habe meine Lösung nicht bearbeitet, da die Lösung von CopsOnRoad ziemlich elegant ist
user1462442
Das habe ich nach einigem Refactoring benutzt: D danke
Koen Van Looveren
In meinem Fall war es die Behälterform, danke für die Lösung
Mohammad Ersan
106

Ausgabe:

Geben Sie hier die Bildbeschreibung ein


Verwenden Sie einfach ein InkWidget in einem InkWell.

InkWell(
  onTap: () {}, // needed
  child: Ink( // use Ink
    width: 200,
    height: 200,
    color: Colors.blue,
  ),
)
CopsOnRoad
quelle
Die Quelle bestätigt Schritt 3: github.com/flutter/flutter/blob/… In jedem Handler prüfen sie, ob der Rückruf verfügbar ist, andernfalls passiert nichts.
Nightking
@CopsOnRoad, darf ich Sie bitten, hier eine Frage zum Flattern zu stellen: stackoverflow.com/questions/60539378/… ?
Istiaque Ahmed
Wenn Sie mit dem vollständigen Code das Beispiel meinen, das Sie gegeben haben, dann ja. Ich habe festgestellt, dass dies die Lösung ist> stackoverflow.com/a/58556613/12140067
Chris
@ Chris Ich denke, Sie haben möglicherweise eine Störung von Theme'oder Material', weil dieser Code den ganzen Tag funktioniert.
CopsOnRoad
1
Dies ist die einzige Lösung, die für mich funktioniert hat
Easazade
24

InkWell () zeigt den Ripple-Effekt erst an, wenn Sie den hinzufügen

onTap : () {} 

oder Rückrufe wie onDoubleTap, onLongPress usw.

Parameter im InkWell, da es nur dann auf Ihre Taps hört, wenn Sie diesen Parameter angeben.

Jaswant Singh
quelle
Ja, das habe ich und es ist wahr. Überprüfen Sie die Quelle: github.com/flutter/flutter/blob/… In jedem Handler wird geprüft , ob der Rückruf verfügbar ist, da sonst nichts passiert.
Nightking
17
  1. Das InkWell-Widget muss ein Material-Widget als Vorfahr haben, da es sonst keine Effekte anzeigen kann. Z.B:

    Material(
      child : InkWell(
        child : .....
    
  2. Sie müssen eine onTapMethode hinzufügen , um die tatsächlichen Effekte wie folgt zu sehen

     Buttons {RaisedButton,FlatButton etc}.
     e.g -> Material(
                 child : InkWell(
                         onTap : (){}
                         child : .....
    

Kommen wir zu den wichtigsten Punkten, sehen wir uns einige Beispiele an und versuchen, die tatsächlichen Konzepte von InkWell zu verstehen.

  • Im folgenden Beispiel ist Material mit onTap übergeordnet zu InkWell, funktioniert jedoch immer noch nicht. Bitte versuchen Sie das Konzept zu verstehen. Sie sollten dem Container oder einem anderen Widget einen gewissen Spielraum geben, um die Auswirkungen anzuzeigen. Eigentlich funktioniert der unten stehende Code einwandfrei, aber wir können ihn nicht sehen, da wir keinen Rand angegeben oder nicht ausgerichtet haben, sodass kein Platz zum Anzeigen der Effekte vorhanden ist.

    Widget build(BuildContext context) {
      return Center(
        child: Material(
          child: new InkWell(
            onTap: () {
              print("tapped");
            },
            child: new Container(
              width: 100.0,
              height: 100.0,
              color: Colors.orange,
            ),  
          ),
        ),
      );
    }
    
  • Das folgende Beispiel zeigt InkWell-Effekte nur nach oben, da wir Platz {Rand} bereitstellen.

    Widget build(BuildContext context) {
      return Center(
        child: Material(
          child: new InkWell(
            onTap: () {
              print("tapped");
            },
            child: new Container(
              margin: EdgeInsets.only(top: 100.0),
              width: 100.0,
              height: 100.0,
              color: Colors.orange,
            ),
          ),
        ),
      );
    }
    
  • Unten exp. Zeigen Sie die Effekte auf der gesamten Seite an, da die Mitte einen Rand von allen Seiten erzeugt. Richten Sie das untergeordnete Widget in der Mitte von oben, links, rechts und unten aus.

    Widget build(BuildContext context) {
      return Center(
        child: Material(
          child: new InkWell(
            onTap: () {
              print("tapped");
            },
            child: Center(
              child: new Container(
                width: 100.0,
                height: 100.0,
                color: Colors.orange,
              ),
            ),
          ),
        ),
      );
     }
    
97loser
quelle
9

Ein besserer Weg ist, das InkWidget anstelle eines anderen Widgets zu verwenden.

Anstatt colorinnerhalb des Containers zu definieren, können Sie ihn im InkWidget selbst definieren.

Der folgende Code wird funktionieren.

Ink(
  color: Colors.orange,
  child: InkWell(
    child: Container(
      width: 100,
      height: 100,
    ),
    onTap: () {},
  ),
)

Vergessen Sie nicht , ein hinzuzufügen , onTap: () {}in dem InkWellsonst wird es nicht die sich allmählich ausbreitende Wirkung zeigen.

ibhavikmakwana
quelle
4

Ich habe diese Lösung für mich gefunden. Ich denke, es kann Ihnen helfen:

Material(
      color: Theme.of(context).primaryColor,
      child: InkWell(
        splashColor: Theme.of(context).primaryColorLight,
        child: Container(
          height: 100,
        ),
        onTap: () {},
      ),
    )

Colorwird an das Material-Widget übergeben. Dies ist die Standardfarbe Ihres Widgets. Sie können die Farbe des Welligkeitseffekts mithilfe der splashColorEigenschaft von Inkwell anpassen .

Kanan Yusubov
quelle
3

Dies ist der beste Weg, den ich gefunden und immer benutzt habe. Du kannst es versuchen.

  • Wickeln Sie Ihre WidgetmitInkWell
  • Wickeln Sie InkWellmitMaterial
  • Stellen Sie die Deckkraft trotzdem auf 0% ein. z.B:color: Colors.white.withOpacity(0.0),

    Material(
      color: Colors.white.withOpacity(0.0),
      child: InkWell(
        child: Container(width: 100, height: 100),
        onTap: (){print("Wow! Ripple");},
      ),
    )
    
Sa Sadik
quelle
2

Ich bin auf dasselbe Problem gestoßen, als ich versucht habe, eine abwechselnde Farbe von InkWells in einer ListView zu erstellen. In diesem speziellen Fall gibt es eine einfache Lösung: Wickeln Sie die Alternativen in einen Container, der eine weitgehend transparente Farbton- / Helligkeitsänderung verwendet. Die InkWell-Touch-Animation ist weiterhin darunter sichtbar. Kein Material benötigt. Beachten Sie, dass es andere Probleme gibt, wenn Sie versuchen, dies mit einem Materal zu umgehen. Beispielsweise wird ein von Ihnen verwendeter DefaultTextStyle mit dem Standardwert überschrieben (es wird ein AnimatedDefaultTextStyle installiert), was sehr schmerzhaft ist.

user3483238
quelle
2

Das funktioniert bei mir:

Material(
    color: Colors.white.withOpacity(0.0),
    child: InkWell(
      splashColor: Colors.orange,
      child: Text('Hello'), // actually here it's a Container wrapping an image
      onTap: () {
        print('Click');
      },
    ));

Nachdem ich hier viele Antworten ausprobiert hatte, war es eine Kombination aus:

  1. Rahmen splashColor
  2. Einwickeln InkWellinMaterial(color: Colors.white.withOpacity(0.0), ..)

Vielen Dank an die Antworten hier, die diese 2 Punkte machen

Gene Bo
quelle
1

Nachdem Sie den onTap:(){}Listener hinzugefügt haben , sollte der Ripple-Effekt einwandfrei funktionieren. Es funktioniert nicht, wenn Sie BoxShadow()mit im InkWell()Widget verwenden.

Aruna Warnasooriya
quelle
Das ist der Trick. Ripple funktioniert nicht ohne onTap (). Danke, Mann!
Hardik Joshi
0

Ich hatte ein ähnliches Problem beim Hinzufügen eines Tintenfasses zu einem vorhandenen komplexen Widget mit einem Container, der eine BoxDecoration mit einer Farbe umhüllt. Durch Hinzufügen des Materials und des Tintenfasses in der vorgeschlagenen Weise wurde das Tintenfass immer noch von der BoxDecoration verdeckt, sodass ich die Farbe der BoxDecoration nur leicht undurchsichtig machte, sodass das Tintenfass sichtbar war

Lee McLoughlin
quelle
0

Die Lösung für kreisförmige Widgets lautet wie folgt:

Material(
    color: Colors.transparent,
    child: Container(
      alignment: Alignment.center,
      height: 100,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          IconButton(
              enableFeedback: true,
              iconSize: 40,
              icon: Icon(
                Icons.skip_previous,
                color: Colors.white,
                size: 40,
              ),
              onPressed: () {}),
          IconButton(
            iconSize: 100,
            enableFeedback: true,
            splashColor: Colors.grey,
            icon: Icon(Icons.play_circle_filled, color: Colors.white, size: 100),
            padding: EdgeInsets.all(0),
            onPressed: () {},
          ),
          IconButton(
              enableFeedback: true,
              iconSize: 40,
              icon: Icon(
                Icons.skip_next,
                color: Colors.white,
                size: 40,
              ),
              onPressed: () {}),
        ],
      ),
    ),
  )
Edeson Bizerril
quelle
0

Für mich war es ein weiteres Problem. InkWell zeigte keinen Welligkeitseffekt, als ich die onTap-Funktion als Parameter meines Widgets hatte, wie unten definiert.

Function(Result) onTapItem;
...
onTap: onTapItem(result),

Ich weiß nicht, was der Unterschied ist, aber der nächste Code funktioniert gut.

onTap: (){ onTapItem(result); },
doof
quelle