forked from lxm_flutter/FlutterUnit
优化 feedback_widget 点击相应
This commit is contained in:
@@ -17,17 +17,19 @@ class FeedbackWidget extends StatefulWidget {
|
||||
final FeedMode mode;
|
||||
final Duration duration;
|
||||
final Function() onPressed;
|
||||
final Function() onEnd;
|
||||
final Function() onLongPressed;
|
||||
final a;
|
||||
|
||||
FeedbackWidget(
|
||||
{@required this.child,
|
||||
this.mode = FeedMode.scale,
|
||||
this.a = 0.9,
|
||||
this.duration = const Duration(milliseconds: 150),
|
||||
@required this.onPressed, this.onLongPressed
|
||||
|
||||
});
|
||||
FeedbackWidget({
|
||||
@required this.child,
|
||||
this.mode = FeedMode.scale,
|
||||
this.a = 0.9,
|
||||
this.onLongPressed,
|
||||
this.duration = const Duration(milliseconds: 150),
|
||||
this.onPressed,
|
||||
this.onEnd,
|
||||
});
|
||||
|
||||
@override
|
||||
_FeedBackState createState() => _FeedBackState();
|
||||
@@ -36,22 +38,34 @@ class FeedbackWidget extends StatefulWidget {
|
||||
class _FeedBackState extends State<FeedbackWidget>
|
||||
with SingleTickerProviderStateMixin {
|
||||
AnimationController _controller;
|
||||
double rate = 1.0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = AnimationController(vsync: this, duration: widget.duration)
|
||||
..addListener(() {
|
||||
setState(() => rate = (widget.a - 1) * _controller.value + 1);
|
||||
})
|
||||
..addStatusListener((s) {
|
||||
_controller = AnimationController(
|
||||
vsync: this,
|
||||
duration: widget.duration,
|
||||
)..addStatusListener((s) {
|
||||
if (s == AnimationStatus.completed) {
|
||||
_controller.reverse();
|
||||
_controller.reverse().then((value) {
|
||||
if (widget.onEnd != null) widget.onEnd();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 当父层状态执行 setState, 当前 State 不会执行 initState,而是 didUpdateWidget,
|
||||
// 因此如果上层状态对某些 widget 配置进行修改,那么当前状态对象便无法知晓,比如 duration 、
|
||||
// 如果配置不同了需要在 didUpdateWidget 回调中更新
|
||||
//
|
||||
@override
|
||||
void didUpdateWidget(FeedbackWidget oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (widget.duration != oldWidget.duration) {
|
||||
_controller.duration = widget.duration;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
@@ -61,19 +75,22 @@ class _FeedBackState extends State<FeedbackWidget>
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onLongPress: widget.onLongPressed,
|
||||
onTap: () {
|
||||
_controller.forward();
|
||||
if(widget.onPressed!=null){
|
||||
widget.onPressed();
|
||||
}
|
||||
},
|
||||
child: _buildByMode(widget.child, widget.mode),
|
||||
);
|
||||
onLongPress: widget.onLongPressed,
|
||||
onTap: () {
|
||||
_controller.forward();
|
||||
if (widget.onPressed != null) {
|
||||
widget.onPressed();
|
||||
}
|
||||
},
|
||||
child: AnimatedBuilder(
|
||||
animation: _controller,
|
||||
child: widget.child,
|
||||
builder: (ctx, child) => _buildByMode(child, widget.mode),
|
||||
));
|
||||
}
|
||||
|
||||
Widget _buildByMode(Widget child, FeedMode mode) {
|
||||
double rate = (widget.a - 1) * _controller.value + 1;
|
||||
switch (mode) {
|
||||
case FeedMode.scale:
|
||||
return Transform.scale(scale: rate, child: widget.child);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_unit/app/router/unit_router.dart';
|
||||
import 'package:flutter_unit/views/components/permanent/circle_image.dart';
|
||||
import 'package:flutter_unit/views/components/permanent/feedback_widget.dart';
|
||||
|
||||
import 'page_item.dart';
|
||||
|
||||
@@ -13,36 +15,43 @@ class MePage extends StatelessWidget {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
Container(
|
||||
height: 180,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Image.asset(
|
||||
'assets/images/sabar_bar.webp',
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
SizedOverflowBox(
|
||||
size: Size(0, 0),
|
||||
child: Align(
|
||||
alignment: Alignment(-0.7, 0),
|
||||
child: CircleImage(
|
||||
size: 80,
|
||||
shadowColor: Theme.of(context).primaryColor.withAlpha(33),
|
||||
image: AssetImage("assets/images/icon_head.webp"),
|
||||
Stack(
|
||||
children: [
|
||||
Container(
|
||||
height: 180,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
margin: EdgeInsets.only(bottom: 40),
|
||||
child: Image.asset(
|
||||
'assets/images/sabar_bar.webp',
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 20, top: 8),
|
||||
child: Text(
|
||||
'张风捷特烈',
|
||||
style: TextStyle(
|
||||
fontSize: 18, color: Theme.of(context).primaryColor),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
left: 40,
|
||||
child: FeedbackWidget(
|
||||
onEnd: (){
|
||||
Navigator.of(context).pushNamed(UnitRouter.login);
|
||||
},
|
||||
child: CircleImage(
|
||||
size: 80,
|
||||
shadowColor: Theme.of(context).primaryColor.withAlpha(33),
|
||||
image: AssetImage("assets/images/icon_head.webp"),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 20,
|
||||
child: Text(
|
||||
'张风捷特烈',
|
||||
style: TextStyle(
|
||||
fontSize: 18, color: Theme.of(context).primaryColor),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
||||
Expanded(child: MePageItem())
|
||||
],
|
||||
));
|
||||
|
||||
@@ -118,7 +118,7 @@ class _HomePageState extends State<HomePage>
|
||||
return FeedbackWidget(
|
||||
a: 0.95,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
onPressed: () => _toDetailPage(model),
|
||||
onEnd: () => _toDetailPage(model),
|
||||
child: HomeItemSupport.get(model, state.itemStyleIndex));
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user