在轻按时如何更改小部件的颜色?

时间:2020-05-29 14:58:53

标签: flutter

我有一个小部件,我想在用户按下它时更改其背景颜色,当按下完成后,它会恢复为原始颜色。

我尝试使用GestureDetector,实现了 onTapDown onTapUp 函数,但是它不起作用:更改颜色和调整颜色需要花费很长时间(〜150ms) ,如果我以正常速度点击,颜色不会改变。

我是一名Android开发人员,我想做的事情是使用选择器在Android中完成的,如下所示:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="..." android:state_pressed="true" />
  <item android:drawable="..." />
</selector>.

但是我不知道该如何处理。我希望这段代码有助于理解我想要实现的目标。

2 个答案:

答案 0 :(得分:0)

您使用GestureDetector做对了,但是使用了错误的方法,使用的方法是onLongPressStartonLongPressEnd,如下例所示:

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _changeColor = false;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: GestureDetector(
        onLongPressStart: (_) => setState(() => _changeColor = !_changeColor),
        onLongPressEnd: (_) => setState(() => _changeColor = !_changeColor),
        child: Container(
          color: _changeColor ? Colors.red : Colors.yellow,
          child: Text('Change color'),
        ),
      ),
    );
  }
}

另一种实现方法是使用@pskink建议的MaterialStateColor

class MyApp extends StatelessWidget {
  Color getTextColor(Set<MaterialState> states) {
    const Set<MaterialState> interactiveStates = <MaterialState>{
      MaterialState.pressed,
      MaterialState.hovered,
      MaterialState.focused,
    };
    if (states.any(interactiveStates.contains)) {
// the color to return when button is in pressed, hovered, focused state
      return Colors.red;
    }
// the color to return when button is in it's normal/unfocused state 
    return Colors.yellow;
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: FlatButton(
        child: Text('FlatButton'),
        onPressed: () {},
        textColor: MaterialStateColor.resolveWith(getTextColor),
      ),
    );
  }
}

答案 1 :(得分:0)

这是我要怎么做:


class MyWidget extends StatefulWidget {

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

class _MyWidgetState extends State<MyWidget> with SingleTickerProviderStateMixin {

  AnimationController _controller;
  Color myColor = Colors.blue;

  @override
  void initState() {
    _controller = AnimationController(vsync: this,duration: Duration(milliseconds: 400));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapUp: (_) {
        setState(() {     
        myColor = Colors.blue;
        });
      },
      onTapDown: (_) {
        setState(() {
        myColor = Colors.red;
        });
      },
       child: AnimatedBuilder(animation: _controller,
       builder: (context, child) => Container(
         height: 200,
         width: 200,
         color : myColor,
       )),
    );
  }
}

如果太慢,可以在animationController中更改持续时间。