InkWell ไม่แสดงผลกระเพื่อม


96

การแตะที่คอนเทนเนอร์จะเรียกonTap()ตัวจัดการ แต่ไม่แสดงเอฟเฟกต์การสาดหมึก

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,
          ),
        ),
      ),
    );
  }
}

ฉันพยายามใส่InkWellด้านในContainerด้วย แต่ก็ไร้ผล

คำตอบ:


152

ฉันคิดว่าการเพิ่มสีลงในภาชนะนั้นครอบคลุมเอฟเฟกต์หมึก

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

ดูเหมือนว่ารหัสนี้จะใช้งานได้

  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,
    ),
  ),

เพียงคลิกสี่เหลี่ยมตรงกลาง

แก้ไข: ฉันพบรายงานข้อบกพร่อง https://github.com/flutter/flutter/issues/3782

เป็นไปตามที่คาดไว้จริง ๆ แม้ว่าเราควรอัปเดตเอกสารเพื่อให้ชัดเจนขึ้น

สิ่งที่เกิดขึ้นคือข้อมูลจำเพาะของวัสดุบอกว่าจริงๆแล้วการกระเด็นนั้นเป็นหมึกบนวัสดุ ดังนั้นเมื่อเราสาดสิ่งที่เราทำก็คือเรามีวิดเจ็ต Material ทำการสาด หากคุณมีอะไรบางอย่างอยู่ด้านบนของวัสดุเราจะกระเด็นไปข้างใต้และคุณจะมองไม่เห็น

ฉันต้องการเพิ่มวิดเจ็ต "MaterialImage" ซึ่งจะพิมพ์ภาพในคอนเซ็ปต์ลงในวัสดุด้วยเช่นกันเพื่อให้การกระเซ็นอยู่เหนือรูปภาพ เราสามารถมี MaterialDecoration ซึ่งทำคล้าย ๆ กับของตกแต่งได้ หรือเราอาจมีวัสดุเป็นของตกแต่ง ตอนนี้ต้องใช้สี แต่เราสามารถขยายไปสู่การตกแต่งทั้งหมดได้ ยังไม่ชัดเจนว่ามันเข้ากันได้กับวัสดุที่มีการไล่ระดับสีหรือไม่ดังนั้นฉันไม่แน่ใจว่าเราควรทำเช่นนั้นหรือไม่

ในระยะสั้นหากคุณต้องการวิธีแก้ไขเบื้องต้นคุณสามารถวางวัสดุไว้ที่ด้านบนของภาชนะบรรจุโดยตั้งค่าวัสดุให้ใช้ประเภท "ความโปร่งใส" จากนั้นจึงใส่หมึกลงไปในนั้น

- hixie

อัปเดต: Hixie ผสานโซลูชัน Ink ใหม่เมื่อปีที่แล้ว หมึกเป็นวิธีที่สะดวกในการสาดภาพ

  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)),
          ),
        )
      ),
    ),
  ),
)

โปรดทราบ: ฉันไม่ได้ทดสอบ Ink Widget ใหม่ ฉันคัดลอกโค้ดจาก ink_paint_test.dart และเอกสารคลาส Ink

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


2
คุณสามารถใส่สีลงบนMaterialตัวมันเองและทิ้งไฟล์Container.
Herohtar

1
ฉันคิดว่าเมื่อ CopsOnRoad โพสต์คำตอบของเขา
user1462442

1
@KoenVanLooveren ลองคำตอบ CopsOnRoad ฉันไม่ได้แก้ไขโซลูชันของฉันเพราะโซลูชันของ CopsOnRoad ค่อนข้างสวยหรู
user1462442

นั่นคือสิ่งที่ฉันใช้หลังจากปรับโครงสร้างใหม่แล้ว: D ขอบคุณ
Koen Van Looveren

ในกรณีของฉันมันเป็นรูปทรงคอนเทนเนอร์ขอบคุณสำหรับการแก้ปัญหา
Mohammad Ersan

106

เอาท์พุต:

ป้อนคำอธิบายภาพที่นี่


เพียงใช้Inkวิดเจ็ตที่รวมอยู่ในInkWellไฟล์.

InkWell(
  onTap: () {}, // needed
  child: Ink( // use Ink
    width: 200,
    height: 200,
    color: Colors.blue,
  ),
)

แหล่งที่มายืนยันขั้นตอนที่ 3: github.com/flutter/flutter/blob/…ในแต่ละตัวจัดการจะตรวจสอบว่ามีการเรียกกลับหรือไม่มิฉะนั้นจะไม่มีอะไรเกิดขึ้น
Nightking

@CopsOnRoad ฉันขอให้คุณมีคำถามเกี่ยวกับการกระพือปีกได้ที่นี่stackoverflow.com/questions/60539378/… ?
Istiaque Ahmed

ถ้าตามรหัสเต็มคุณหมายถึงตัวอย่างที่คุณระบุใช่ ฉันพบว่านี่เป็นวิธีแก้ปัญหา> stackoverflow.com/a/58556613/12140067
คริส

@ Chris ฉันคิดว่าคุณอาจจะมีบางคนTheme'หรือMaterial' s รบกวนเพราะรหัสนี้จะทำงานได้ตลอดทั้งวัน
CopsOnRoad

1
นี่เป็นทางออกเดียวที่ใช้ได้สำหรับฉัน
easazade

24

InkWell () จะไม่แสดงเอฟเฟกต์การกระเพื่อมจนกว่าคุณจะเพิ่มไฟล์

onTap : () {} 

หรือการเรียกกลับใด ๆ เช่น onDoubleTap, onLongPress เป็นต้น

ภายใน InkWell เมื่อเริ่มฟังก๊อกของคุณก็ต่อเมื่อคุณระบุพารามิเตอร์นี้


ใช่ฉันทำและมันเป็นความจริง ตรวจสอบแหล่งที่มา: github.com/flutter/flutter/blob/…ในแต่ละตัวจัดการจะตรวจสอบว่ามีการโทรกลับหรือไม่มิฉะนั้นจะไม่มีอะไรเกิดขึ้น
Nightking

17
  1. วิดเจ็ต InkWell ต้องมีวิดเจ็ต Material เป็นบรรพบุรุษมิฉะนั้นจะไม่สามารถแสดงเอฟเฟกต์ได้ เช่น:

    Material(
      child : InkWell(
        child : .....
    
  2. คุณต้องเพิ่มonTapวิธีการเพื่อดูเอฟเฟกต์จริงตามต้องการ

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

มาที่ประเด็นหลักดูตัวอย่างด้านล่างและพยายามทำความเข้าใจแนวคิดที่แท้จริงของ InkWell

  • ในตัวอย่างด้านล่าง Material เป็นพาเรนต์ของ InkWell ที่มี onTap แต่ยังใช้งานไม่ได้ โปรดพยายามทำความเข้าใจแนวคิดของมัน คุณควรกำหนดระยะขอบให้กับคอนเทนเนอร์หรือวิดเจ็ตอื่น ๆ เพื่อแสดงเอฟเฟกต์ โค้ดด้านล่างทำงานได้ดี แต่เรามองไม่เห็นเนื่องจากเราไม่ได้จัดให้มีระยะขอบหรือจัดแนวดังนั้นจึงไม่มีพื้นที่สำหรับแสดงเอฟเฟกต์

    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,
            ),  
          ),
        ),
      );
    }
    
  • ตัวอย่างด้านล่างนี้แสดงเอฟเฟกต์ InkWell ขึ้นไปเท่านั้นเนื่องจากเราให้พื้นที่ {margin}

    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,
            ),
          ),
        ),
      );
    }
    
  • ประสบการณ์ด้านล่าง แสดงเอฟเฟกต์ในทุกหน้าเนื่องจากศูนย์กลางสร้างระยะขอบจากด้านข้างทั้งหมด จัดกึ่งกลางของวิดเจ็ตลูกจากด้านบนซ้ายขวาและล่าง

    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,
              ),
            ),
          ),
        ),
      );
     }
    

9

วิธีที่ดีกว่าคือใช้Inkวิดเจ็ตแทนวิดเจ็ตอื่น ๆ

แทนที่จะกำหนดcolorภายในคอนเทนเนอร์คุณสามารถกำหนดในInkวิดเจ็ตเอง

โค้ดด้านล่างจะทำงาน

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

อย่าลืมเพิ่มonTap: () {}ในส่วนInkWellอื่นจะไม่แสดงเอฟเฟกต์ระลอกด้วย


4

ฉันได้พบวิธีนี้สำหรับฉันแล้ว ฉันคิดว่ามันช่วยคุณได้:

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

Colorมอบให้กับวิดเจ็ต Material เป็นสีเริ่มต้นของวิดเจ็ตของคุณ คุณสามารถปรับสีของเอฟเฟกต์ระลอกคลื่นโดยใช้splashColorคุณสมบัติของ Inkwell


3

นี่เป็นวิธีที่ดีที่สุดที่ฉันพบและใช้ได้เสมอ คุณสามารถลอง

  • ห่อWidgetด้วยInkWell
  • ห่อInkWellด้วยMaterial
  • ตั้งค่าความทึบ 0% อย่างไรก็ได้ เช่น: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");},
      ),
    )
    

2

ฉันพบปัญหาเดียวกันนี้โดยพยายามสร้างสีสลับของ InkWell ใน ListView ในกรณีนั้นมีวิธีง่ายๆ: ห่อทางเลือกอื่นในคอนเทนเนอร์ที่ใช้การเปลี่ยนแปลงสี / ความสว่างที่โปร่งใสเป็นส่วนใหญ่ - ภาพเคลื่อนไหวแบบสัมผัส InkWell จะยังคงมองเห็นได้ด้านล่าง ไม่จำเป็นต้องใช้วัสดุ โปรดทราบว่ามีปัญหาอื่น ๆ เมื่อพยายามแก้ไขปัญหานี้ด้วย Materal เช่นจะแทนที่ DefaultTextStyle ที่คุณใช้กับค่าเริ่มต้น (ติดตั้ง AnimatedDefaultTextStyle) ซึ่งเป็นความเจ็บปวดอย่างมาก


2

สิ่งนี้ใช้ได้ผลสำหรับฉัน:

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');
      },
    ));

หลังจากลองหลาย ๆ คำตอบที่นี่มันเป็นการรวมกันของ:

  1. การตั้งค่า splashColor
  2. ห่อInkWellในMaterial(color: Colors.white.withOpacity(0.0), ..)

ขอบคุณคำตอบที่ทำให้ 2 คะแนนนี้


1

หลังจากที่คุณเพิ่มonTap:(){}ผู้ฟังแล้วเอฟเฟกต์ระลอกคลื่นจะทำงานได้ดี ไม่ได้ผลหากคุณใช้BoxShadow()กับในInkWell()วิดเจ็ต


นั่นคือเคล็ดลับ Ripple จะไม่ทำงานหากไม่มี onTap () ขอบคุณ!
Hardik Joshi

0

ฉันประสบปัญหาที่คล้ายกันในการเพิ่ม Inkwell ไปยังวิดเจ็ตที่ซับซ้อนที่มีอยู่ด้วย Container ที่ห่อ BoxDecoration ด้วยสี ด้วยการเพิ่ม Material และ Inkwell ตามวิธีที่แนะนำว่า Inkwell ยังคงถูกบดบังด้วย BoxDecoration ดังนั้นฉันจึงทำให้สีของ BoxDecoration ขุ่นเล็กน้อยซึ่งทำให้สามารถมองเห็น Inkwell ได้


0

วิธีแก้ปัญหาสำหรับวิดเจ็ตแบบวงกลมทำดังนี้:

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: () {}),
        ],
      ),
    ),
  )

0

สำหรับฉันมันเป็นปัญหาอื่น InkWell ไม่แสดงผลกระเพื่อมเมื่อฉันมีฟังก์ชัน onTap เป็นพารามิเตอร์ของวิดเจ็ตของฉันที่กำหนดไว้ด้านล่าง

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

ฉันไม่รู้ว่าอะไรคือความแตกต่าง แต่โค้ดถัดไปทำงานได้ดี

onTap: (){ onTapItem(result); },
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.