ScaleTransition看起来像是从右向左滑动一样



我正在尝试制作一个缩小并重新出现在另一侧的小部件,我希望它缩小和放大,无论其对齐方式如何。但是当我尝试时,它看起来像是从右向左滑动的。

尝试从_buildRightAlignedListTile中删除ListTile并直接使用文本和分配给它ValueKey,但它看起来仍然相同。

有什么办法可以防止这种情况吗?

呵��̶/̶/̶d̶a̶r̶t̶p̶a̶d̶v̶)̶,̶p̶l̶e̶a̶s̶e̶ ̶h̶a̶v̶e̶

̶a̶ ̶l̶o̶o̶k̶。

编辑

终于找到了分享的方法,请使用此DartPad链接重现该问题。

您还可以复制并粘贴下面的脚本,以防链接失效。它直接由飞镖垫制成。

编辑 2

如果我的解释令人困惑,我深表歉意,我很难找到合适的词来解释它。我不是母语人士。

我希望右对齐的小部件保持在右侧并按原位缩小,直到它完全消失。然后左对齐的小部件在左侧放大,而不是从中间向左放大。

import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _active = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: SwitchingWidget(active: _active),
),
floatingActionButton: FloatingActionButton(
onPressed: _toggle,
child: const Icon(Icons.check)
),
),
);
}
void _toggle() {
setState(() {
_active = !_active;
});
}
}
class SwitchingWidget extends StatefulWidget {
const SwitchingWidget({super.key, this.active = false});
final bool active;
@override
State<SwitchingWidget> createState() => _SwitchingWidgetState();
}
class _SwitchingWidgetState extends State<SwitchingWidget> {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 200),
transitionBuilder: (child, animation) {
return ScaleTransition(scale: animation, child: child);
},
child: widget.active
? _buildLeftAlignedListTile()
: _buildRightAlignedListTile(),
),
);
}

Widget _buildLeftAlignedListTile() {
return const ListTile(
key: ValueKey(1),
leading: SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white),
),
title: Text(
'Left aligned',
style: TextStyle(color: Colors.white),
),
);
}

Widget _buildRightAlignedListTile() {
return const ListTile(
key: ValueKey(2),
title: Text(
'Right aligned',
textAlign: TextAlign.right,
style: TextStyle(color: Colors.white),
),
);
}
}

在修补另一个东西时找到了解决这个问题的方法。解决方案是为我要动画的每个小部件使用单独的AnimatedSwitcher,而不是使用一个并直接使用条件语句放置它。

上面的脚本略有修改,它就像我想要的那样完美地工作。您还可以复制和粘贴以在DartPad上运行它,因为它是从那里制作的,可以试用它。

如果有更好的方法,请告诉我!

import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _active = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: SwitchingWidget(active: _active),
),
floatingActionButton: FloatingActionButton(
onPressed: _toggle,
child: const Icon(Icons.check)
),
),
);
}
void _toggle() {
setState(() {
_active = !_active;
});
}
}
class SwitchingWidget extends StatefulWidget {
const SwitchingWidget({super.key, this.active = false});
final bool active;
@override
State<SwitchingWidget> createState() => _SwitchingWidgetState();
}
class _SwitchingWidgetState extends State<SwitchingWidget> {
final scaleDuration = const Duration(milliseconds: 200);
Widget transitionBuilder(child, animation) {
return ScaleTransition(child: child, scale: animation);
}

@override
Widget build(BuildContext context) {  
return Container(
color: Colors.red,
height: 60,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
AnimatedSwitcher(
duration: scaleDuration,
transitionBuilder: transitionBuilder,
child: widget.active
? const SizedBox()
: _buildLeftAlignedWidget(),
),
AnimatedSwitcher(
duration: scaleDuration,
transitionBuilder: transitionBuilder,
child: widget.active
? _buildRightAlignedWidget()
: const SizedBox(),
),
],
),
);
}

Widget _buildLeftAlignedWidget() {
return Row(
key: const ValueKey(1),
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
margin: const EdgeInsets.only(right: 16),
width: 20,
height: 20,
child: const CircularProgressIndicator(color: Colors.white, strokeWidth: 2),
),
const Text(
'Left aligned',
style: TextStyle(color: Colors.white),
),
],
);
}

Widget _buildRightAlignedWidget() {
return const Text(
key: ValueKey(2),
'Right aligned',
textAlign: TextAlign.right,
style: TextStyle(color: Colors.white),
);
}
}

相关内容

最新更新