从下面的 GIF 中可以看出,每当子进程退出父进程时
Container
,子进程就会消失且没有动画,这给用户留下了不好的印象。 如何为进入和退出的子进程添加平滑过渡出口?
Chat GPT 给出了一个看似逻辑正确的答案,但它给出了同样突然的效果。
聊天 GPT 代码:-
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Smooth Transition in ListWheelScrollView')),
body: TransitionListWheel(),
),
);
}
}
class TransitionListWheel extends StatefulWidget {
@override
_TransitionListWheelState createState() => _TransitionListWheelState();
}
class _TransitionListWheelState extends State<TransitionListWheel> {
FixedExtentScrollController _scrollController;
double itemHeight = 100.0; // Height of each item in the list
int itemCount = 20;
@override
void initState() {
super.initState();
_scrollController = FixedExtentScrollController();
_scrollController.addListener(_handleScroll);
}
@override
void dispose() {
_scrollController.removeListener(_handleScroll);
_scrollController.dispose();
super.dispose();
}
void _handleScroll() {
setState(() {
// Trigger a rebuild to update the transition animations
});
}
@override
Widget build(BuildContext context) {
return Center(
child: Container(
height: itemHeight * 5, // Visible height of the list
child: ListWheelScrollView.useDelegate(
controller: _scrollController,
itemExtent: itemHeight,
physics: FixedExtentScrollPhysics(),
childDelegate: ListWheelChildBuilderDelegate(
builder: (context, index) {
final double scrollOffset = _scrollController.offset;
final double itemScrollOffset = scrollOffset % itemHeight;
// Calculate transition values for entering and exiting animations
final double enteringScale = 1.0 - (itemScrollOffset / itemHeight);
final double exitingScale = itemScrollOffset / itemHeight;
return AnimatedBuilder(
animation: _scrollController,
builder: (context, child) {
return Transform.scale(
scale: (enteringScale + exitingScale).clamp(0.6, 1.0), // Adjust the range as needed
child: child,
);
},
child: Center(
child: Container(
width: 200,
height: 80,
color: Colors.blue,
child: Center(
child: Text(
'Item $index',
style: TextStyle(color: Colors.white),
),
),
),
),
);
},
childCount: itemCount,
),
),
),
);
}
}
我使用的代码:-
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'List',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: const List(),
);
}
}
class List extends StatefulWidget {
const List({Key? key}) : super(key: key);
@override
_ListState createState() => _ListState();
}
class _ListState extends State<List> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SizedBox(
height: 500,
child: ListWheelScrollView(
itemExtent: 100,
physics: const FixedExtentScrollPhysics(),
onSelectedItemChanged: (value) {
},
children: [
for (int i = 0; i < 5; i++) ...[
Container(
color: Colors.green,
height: 50,
width: 50,
)
]
]),
),
));
}
}
我认为这个包可以解决您的问题。 https://pub.dev/packages/clickable_list_wheel_view
示例:
import 'package:clickable_list_wheel_view/clickable_list_wheel_widget.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Material(
child: MyHomePage(),
),
);
}
}
class MyHomePage extends StatelessWidget {
final _scrollController = FixedExtentScrollController();
static const double _itemHeight = 60;
static const int _itemCount = 100;
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: ClickableListWheelScrollView(
scrollController: _scrollController,
itemHeight: _itemHeight,
itemCount: _itemCount,
onItemTapCallback: (index) {
print("onItemTapCallback index: $index");
},
child: ListWheelScrollView.useDelegate(
controller: _scrollController,
itemExtent: _itemHeight,
physics: FixedExtentScrollPhysics(),
overAndUnderCenterOpacity: 0.5,
perspective: 0.002,
onSelectedItemChanged: (index) {
print("onSelectedItemChanged index: $index");
},
childDelegate: ListWheelChildBuilderDelegate(
builder: (context, index) => _child(index),
childCount: _itemCount,
),
),
),
),
);
}
Widget _child(int index) {
return SizedBox(
height: _itemHeight,
child: ListTile(
leading: Icon(
IconData(int.parse("0xe${index + 200}"),
fontFamily: 'MaterialIcons'),
size: 50),
title: Text('Heart Shaker'),
subtitle: Text('Description here'),
),
);
}
}
我无法将其发布在这里,因为 gif 尺寸很大。您可以从我共享的链接中看到此代码的输出:https://raw.githubusercontent.com/cilestal/clickable_list_wheel_view/master/example/example.gif
我希望我有所帮助。享受你的工作。