Flutter实现仿Telegram自定义可拖拽BottomSheet
实现Telegram风格的BottomSheet头部动态展开效果
Telegram应用有个实用特性:其内置的BottomSheet在向上滑动到距离顶部特定距离时,会自动增大头部高度并显示AppBar。我尝试使用DraggableScrollableSheet来实现该交互,即使借助ChatGPT的帮助也没能达成预期效果,以下是我的示例代码和效果示意图:

import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Draggable Bottom Sheet', theme: ThemeData( primarySwatch: Colors.blue, ), home: DraggableBottomSheetExample(), ); } } class DraggableBottomSheetExample extends StatefulWidget { @override _DraggableBottomSheetExampleState createState() = _DraggableBottomSheetExampleState(); } class _DraggableBottomSheetExampleState extends State<DraggableBottomSheetExample> with TickerProviderStateMixin { late AnimationController _controller; late Animation<double> _textSizeAnimation; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: Duration(milliseconds: 300), ); _textSizeAnimation = Tween<double>(begin: 24.0, end: 48.0).animate( CurvedAnimation( parent: _controller, curve: Curves.easeInOut, ), ); } @override void dispose() { _controller.dispose(); super.dispose(); } void _onScroll(double offset) { if (offset >= 0.8 && !_controller.isAnimating && !_controller.isCompleted) { _controller.forward(); } else if (offset < 0.8 && !_controller.isAnimating && _controller.isCompleted) { _controller.reverse(); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Draggable Bottom Sheet Example'), ), body: Stack( children: <Widget>[ Center( child: ElevatedButton( onPressed: () { showModalBottomSheet( context: context, isScrollControlled: true, builder: (BuildContext context) { return DraggableScrollableSheet( initialChildSize: 0.3, minChildSize: 0.1, maxChildSize: 0.8, builder: (context, scrollController) { scrollController.addListener(() { _onScroll(scrollController.position.pixels / scrollController.position.maxScrollExtent); }); return Container( color: Colors.blueGrey[200], child: SingleChildScrollView( controller: scrollController, child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ AnimatedBuilder( animation: _controller, builder: (context, child) { return Text( 'Draggable Bottom Sheet', style: TextStyle( fontSize: _textSizeAnimation.value, fontWeight: FontWeight.bold, ), ); }, ), SizedBox(height: 16), Text( 'Swipe up to expand or down to collapse.', style: TextStyle(fontSize: 16), ), SizedBox(height: 16), // Add more content here Container( height: 500, color: Colors.blue[100], ), ], ), ), ), ); }, ); }, ); }, child: Text('Show Draggable Bottom Sheet'), ), ), ], ), ); } }
内容的提问来源于stack exchange,提问作者DolDurma
相关产品推荐
相关产品推荐

