我有一个小部件,我想在用户按下它时更改其背景颜色,当按下完成后,它会恢复为原始颜色。
我尝试使用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>.
但是我不知道该如何处理。我希望这段代码有助于理解我想要实现的目标。
答案 0 :(得分:0)
您使用GestureDetector
做对了,但是使用了错误的方法,使用的方法是onLongPressStart
和onLongPressEnd
,如下例所示:
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中更改持续时间。