hover/pressed 上的色调图像

Tint image on hover/pressed

我有一个接受文本和图标的按钮小部件。我想在用户 hover/taps 按钮时对图像进行着色。我怎样才能做到这一点?我不想要涟漪效果,只想要白色。

class SquareButton extends StatelessWidget {
  final String icon;
  final String text;

  SquareButton(this.icon, this.text);

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
        onTap: () { print(text); },
        child: Stack(
          alignment: Alignment.bottomCenter,
          children: [
            Image(
              image: AssetImage(icon),
              fit: BoxFit.cover,
            ),
            Container(
                height: 30,
                child: Text(
                  text,
                  style: TextStyle(
                      color: Colors.white,
                      fontStyle: FontStyle.italic
                  ),
                )
            ),
          ],
        )
    );
  }
}

您可以尝试的一种方法是这样的。

class SquareButton extends StatefulWidget {
  final String icon;
  final String text;

  SquareButton(this.icon, this.text);

  @override
  _SquareButtonState createState() => _SquareButtonState();
}

class _SquareButtonState extends State<SquareButton> {
  bool isTapped = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: (_) {
        setState(() {
          isTapped = true;
        });
      },
      onTapUp: (_) {
        setState(() {
          isTapped = false;
        });
      },
      onTap: () { print(widget.text); },
      child: Stack(
        alignment: Alignment.bottomCenter,
        children: [
          Image.asset(
            widget.icon,
            fit: BoxFit.cover,
            color: isTapped ? Colors.white : null,
          ),
          Container(height: 30, child: Text(widget.text, style: TextStyle(color: Colors.white, fontStyle: FontStyle.italic,),),),
        ],
      ),
    );
  }
}

我同意@Jigar Patel。但是我们还需要 onTapCancle() 当你点击和滑动你的手指时 onTapCancle() 会调用而不是 onTapUp() 所以更好的答案是:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'My App',
    home: MyApp(),
  ));
}

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return MyAppState();
  }
}

class MyAppState extends State<MyApp> {
  bool isTapped = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My App'),
      ),
      body: Center(
        child: GestureDetector(
          onTapDown: (value) {
            setState(() {
              print('onTapDown');
              isTapped = true;
            });
          },
          onTapUp: (value) {
            setState(() {
              print('onTapUp');
              isTapped = false;
            });
          },
          onTapCancel: () {
            setState(() {
              print('onTapCancel');
              isTapped = false;
            });
          },
          child: _getImage(),
        ),
      ),
    );
  }

  Widget _getImage() {
    AssetImage image = AssetImage('images/icon.png');
    return Image(
      image: image,
      width: 100.0,
      height: 100.0,
      color: isTapped ? Colors.deepOrangeAccent : Colors.orange,
    );
  }
}

我最终得到了与其他答案类似的结果,但我使用了一个覆盖容器,我对其进行动画处理以模仿水龙头。我觉得 Flutter 应该有更好的方法来解决这类问题,但也许没有。

class SquareButton extends StatefulWidget {
  final String icon;
  final String text;

  SquareButton(this.icon, this.text);

  @override
  _SquareButtonState createState() => _SquareButtonState();
}

class _SquareButtonState extends State<SquareButton> {
  Color color = Colors.transparent;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
        onTapDown: (TapDownDetails details) {
          setState(() {
            color = Colors.black.withOpacity(0.2);
          });
        },
        onTapUp: (TapUpDetails details) {
          setState(() {
            color = Colors.transparent;
          });
        },
        onTapCancel: () {
          setState(() {
            color = Colors.transparent;
          });
        },
        child: Stack(
          alignment: Alignment.bottomCenter,
          children: [
            Image(
              image: AssetImage(widget.icon),
              fit: BoxFit.cover,
            ),
            Container(
                height: 30,
                child: Text(
                  widget.text,
                  style: TextStyle(
                      color: Colors.white,
                      fontStyle: FontStyle.italic
                  ),
                )
            ),
            AnimatedContainer(
                color: color,
                duration: Duration(milliseconds: 50),
            )
          ],
        )
    );
  }
}