我希望在应用程序屏幕主体的左侧放置一个迷你按钮,用于打开Flutter中的迷你抽屉。为了能够弄清楚它,我准备了以下图像:
如图所示,当用户点击迷你按钮时,迷你抽屉式面板进入,当用户再次点击同一按钮时,它关闭面板。谢谢你
bvjveswy1#
这段代码将允许您使用endDrawer作为您的迷你抽屉,您的主抽屉也将在那里。您可以在网上查看,根据您的需要自定义结束抽屉的用户界面。
endDrawer
import 'package:flutter/material.dart'; void main() { runApp(const MainApp()); } class MainApp extends StatelessWidget { const MainApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: Scaffold( body: TwoDrawers(), ), ); } } class TwoDrawers extends StatelessWidget { const TwoDrawers({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Mini Drawer"), actions: const [SizedBox()], ), drawer: Drawer( child: Container( color: Colors.blue, child: const Center( child: Text( "Main Drawer", style: TextStyle(color: Colors.white, fontSize: 30), ), ), ), ), endDrawer: SizedBox( height: 300, child: Drawer( elevation: 0, backgroundColor: Colors.indigo, child: Row( children: [ IconButton( onPressed: () { Navigator.of(context).pop(); }, icon: const Icon(Icons.chevron_right), color: Colors.white, ), Container( width: 240, color: Colors.indigo, child: const Center( child: Text( "Mini Drawer", style: TextStyle(color: Colors.white, fontSize: 30), ), ), ), ], ), ), ), body: Stack( children: [ Positioned( height: 40, top: 250, right: -30, child: SizedBox( child: Builder( builder: (context) { return ElevatedButton( style: ButtonStyle( backgroundColor: const MaterialStatePropertyAll(Colors.indigo), shape: MaterialStatePropertyAll( RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), padding: const MaterialStatePropertyAll( EdgeInsets.only(right: 30), ), ), onPressed: () { Scaffold.of(context).openEndDrawer(); }, child: const Icon(Icons.chevron_left), ); }, ), ), ), ], ), ); } }
一些快照:| 屏幕|主抽屉|迷你抽屉|| --|--|--|||||
lsmd5eda2#
您可以创建自己的小部件,如下面的示例。
import 'dart:math'; import 'package:flutter/material.dart'; class MiniDrawer extends StatefulWidget { final Widget child; final Widget drawerContent; final Duration animationDuration; final Size drawerSize; final Size drawerButtonSize; final Color background; final Color iconColor; const MiniDrawer({ super.key, required this.child, required this.drawerContent, this.iconColor = Colors.white, this.background = const Color.fromRGBO(255, 120, 0, 1), this.drawerSize = const Size(250, 300), this.drawerButtonSize = const Size(50, 90), this.animationDuration = const Duration(milliseconds: 200), }); @override State<MiniDrawer> createState() => _MiniDrawerState(); } class _MiniDrawerState extends State<MiniDrawer> { bool _isOpen = false; @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, constraints) { return Stack( clipBehavior: Clip.none, children: [ widget.child, _buildDrawer(constraints), ], ); }); } Widget _buildDrawer(BoxConstraints constraints) { return AnimatedPositioned( duration: widget.animationDuration, top: constraints.maxHeight / 2 - widget.drawerSize.height / 2, left: _isOpen ? 0 : min(-widget.drawerSize.width, constraints.maxWidth), child: SizedBox( height: widget.drawerSize.height, width: widget.drawerSize.width + widget.drawerButtonSize.width, child: Stack( alignment: Alignment.centerRight, clipBehavior: Clip.none, children: [ _buildDrawerBtn(), Row( children: [ Expanded( child: SingleChildScrollView( child: Container( constraints: BoxConstraints(minHeight: widget.drawerButtonSize.height), color: widget.background, child: widget.drawerContent, ), ), ), SizedBox(width: widget.drawerButtonSize.width), ], ), ], ), ), ); } Widget _buildDrawerBtn() { Radius radius = Radius.circular(widget.drawerButtonSize.height / 2); return Positioned( right: 10, child: GestureDetector( onTap: () { setState(() { _isOpen = !_isOpen; }); }, child: Container( decoration: BoxDecoration( color: widget.background, borderRadius: BorderRadius.only( topRight: radius, bottomRight: radius, ), ), width: widget.drawerButtonSize.width, height: widget.drawerButtonSize.height, child: AnimatedRotation( duration: widget.animationDuration, turns: _isOpen ? 0.5 : 0, child: Icon( Icons.chevron_right, size: 32, color: widget.iconColor, ), ), ), ), ); } }
然后你可以像这样在代码中使用这个小部件。
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('app bar')), body: MiniDrawer( drawerContent: Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: List.generate( 10, (index) => ListTile( title: Text('Item $index'), ), ), ), ), child: const Column( children: [ Text('Page content'), ], ), ), ); }
2条答案
按热度按时间bvjveswy1#
这段代码将允许您使用
endDrawer
作为您的迷你抽屉,您的主抽屉也将在那里。您可以在网上查看,根据您的需要自定义结束抽屉的用户界面。
一些快照:
| 屏幕|主抽屉|迷你抽屉|
| --|--|--|
|
|
|
|
lsmd5eda2#
您可以创建自己的小部件,如下面的示例。
然后你可以像这样在代码中使用这个小部件。