详情里的对话框切换动画ok

This commit is contained in:
zhutao
2025-09-04 23:24:48 +08:00
parent 0231dcfe1a
commit 70aa3e6ab6
8 changed files with 368 additions and 41 deletions

View File

@@ -1,6 +1,9 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:remixicon/remixicon.dart';
import '../viewmodel/plan_detail_store.dart';
class AvatarCard extends StatefulWidget {
const AvatarCard({super.key});
@@ -9,23 +12,35 @@ class AvatarCard extends StatefulWidget {
}
class _AvatarCardState extends State<AvatarCard> with SingleTickerProviderStateMixin {
bool _isShow = false;
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 400),
duration: Duration(milliseconds: 300),
);
_animation = Tween<double>(begin: 0, end: 1).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
),
);
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
void _toggleShow() {
var store = context.read<PlanDetailStore>();
setState(() {
_isShow = !_isShow;
if (_isShow) {
store.showRoleTalk = !store.showRoleTalk;
if (store.showRoleTalk) {
_controller.forward();
} else {
_controller.reverse();
@@ -41,11 +56,10 @@ class _AvatarCardState extends State<AvatarCard> with SingleTickerProviderStateM
offset: Offset(0, 50),
child: Column(
children: [
Transform(
alignment: Alignment.center,
transform: Matrix4.identity()..translate(40.0, 40.0)..scale(0.2),
BothSizeTransition(
animation: _animation,
offset: Offset(50, 50),
child: Container(
color: Colors.red,
padding: EdgeInsets.only(bottom: 10),
child: InkWell(
onTap: _toggleShow,
@@ -84,10 +98,14 @@ class _AvatarCardState extends State<AvatarCard> with SingleTickerProviderStateM
Positioned(
top: 20,
child: Transform.translate(
offset: Offset(50, -10),
offset: Offset(40, -10),
child: GestureDetector(
onTap: _toggleShow,
child: Icon(RemixIcons.message_2_line, size: 26),
child: BothSizeTransition(
animation: ReverseAnimation(_animation),
offset: Offset(-50, -50),
child: Icon(RemixIcons.message_2_line),
),
),
),
),
@@ -101,6 +119,7 @@ class _AvatarCardState extends State<AvatarCard> with SingleTickerProviderStateM
}
}
///聊天气泡三角
class BubblePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
@@ -135,3 +154,47 @@ class BubblePainter extends CustomPainter {
return true;
}
}
///缩放动画
class BothSizeTransition extends StatelessWidget {
final Animation<double> animation;
final Widget child;
final Offset offset;
const BothSizeTransition({
super.key,
required this.animation,
this.offset = Offset.zero,
required this.child,
});
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: animation,
builder: (_, child) {
return Align(
alignment: Alignment(0.7, 1),
child: Opacity(
opacity: animation.value,
child: Transform(
alignment: Alignment(0.5, 1),
transform: Matrix4.identity()
..translate(
offset.dx * (1 - animation.value),
offset.dy * (1 - animation.value),
)
..scale(animation.value, 1.0),
child: SizeTransition(
sizeFactor: animation,
axis: Axis.vertical,
child: child,
),
),
),
);
},
child: child,
);
}
}