我想创建一个可扩展的容器,其中包含多个控件,例如文本输入和按钮。
所以我已经实现了底部工作表,但我想将此位置设置在顶部。
代码:
Widget build(BuildContext context) {
return Container(
child: Center(
child: RaisedButton(
child: Text('Show Buttom Sheet'),
onPressed: () {
showModalBottomSheet(context: context, builder: (context){
return StreamBuilder(
stream: controller.stream,
builder:(context,snapshot) => GestureDetector(
onVerticalDragUpdate: (DragUpdateDetails details)
{
position = MediaQuery.of(context).size.height-
details.globalPosition.dy;
print('position dy = ${position}');
position.isNegative?Navigator.pop(context)
:controller.add(position);
},
behavior: HitTestBehavior.translucent,
child:
Container(
color: Colors.red,
height: snapshot.hasData ? snapshot.data:200.0,
width: double.infinity,
child: Text('Child'),
)),
);
});
}),
),
);
}
查看底页的材料设计参考,它确实表明使用符合人体工程学,这意味着它应该位于底部,因为它更容易用拇指触及(使用手机时)。似乎没有其他“顶部工作表”的示例,这意味着有更好的方法来处理位于屏幕顶部的按钮的单击。例如,在 Gmail 中,单击您的头像会生成一张位于按钮下方的卡片。
话虽如此,这是创建“顶层”的一种方法:
IconButton(
icon: Icon(Icons.star),
onPressed: () {
return showGeneralDialog(
context: context,
barrierDismissible: true,
transitionDuration: Duration(milliseconds: 500),
barrierLabel: MaterialLocalizations.of(context).dialogLabel,
barrierColor: Colors.black.withOpacity(0.5),
pageBuilder: (context, _, __) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: Card(
child: ListView(
shrinkWrap: true,
children: <Widget>[
ListTile(
title: Text('Item 1'),
onTap: () => Navigator.of(context).pop('item1'),
),
ListTile(
title: Text('Item 2'),
onTap: () => Navigator.of(context).pop('item2'),
),
ListTile(
title: Text('Item 3'),
onTap: () => Navigator.of(context).pop('item3'),
),
],
),
),
),
],
);
},
transitionBuilder: (context, animation, secondaryAnimation, child) {
return SlideTransition(
position: CurvedAnimation(
parent: animation,
curve: Curves.easeOut,
).drive(Tween<Offset>(
begin: Offset(0, -1.0),
end: Offset.zero,
)),
child: child,
);
},
);
}
);
删除图标按钮返回后它将起作用。
import 'dart:async';
import 'package:flutter/material.dart';
Future<void> main() async {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Center(
child: Padding(
padding: const EdgeInsets.only(top: 50),
child: IconButton(
icon: const Icon(Icons.star),
onPressed: () {
showGeneralDialog(
context: context,
barrierDismissible: true,
transitionDuration: Duration(milliseconds: 500),
barrierLabel:
MaterialLocalizations.of(context).dialogLabel,
barrierColor: Colors.black.withOpacity(0.5),
pageBuilder: (context, _, __) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
color: Colors.white,
child: Card(
child: ListView(
shrinkWrap: true,
children: <Widget>[
ListTile(
title: Text('Item 1'),
onTap: () =>
Navigator.of(context).pop('item1'),
),
ListTile(
title: Text('Item 2'),
onTap: () =>
Navigator.of(context).pop('item2'),
),
ListTile(
title: Text('Item 3'),
onTap: () =>
Navigator.of(context).pop('item3'),
),
],
),
),
),
],
);
},
transitionBuilder:
(context, animation, secondaryAnimation, child) {
return SlideTransition(
position: CurvedAnimation(
parent: animation,
curve: Curves.easeOut,
).drive(Tween<Offset>(
begin: Offset(0, -1.0),
end: Offset.zero,
)),
child: child,
);
},
);
}),
),
),
],
),
);
}
}