如何将底部工作表位置设置为顶部

问题描述 投票:0回答:3

我想创建一个可扩展的容器,其中包含多个控件,例如文本输入和按钮。

所以我已经实现了底部工作表,但我想将此位置设置在顶部。

代码:

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'),
                      )),
                );

              });

            }),
      ),
    );
  }
flutter flutter-layout flutter-animation
3个回答
21
投票

查看底页的材料设计参考,它确实表明使用符合人体工程学,这意味着它应该位于底部,因为它更容易用拇指触及(使用手机时)。似乎没有其他“顶部工作表”的示例,这意味着有更好的方法来处理位于屏幕顶部的按钮的单击。例如,在 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,
        );
      },
    );
  }
);

1
投票

我认为你想要的小部件是 BackDrop。

示例在这里

并且从 实际 Flutter Gallery 他们也在选项中使用它


0
投票

删除图标按钮返回后它将起作用。

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,
                        );
                      },
                    );
                  }),
            ),
          ),
        ],
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.