Flutter 20: 图解【分享页面】底部对话框

简介: 0 基础学习 Flutter,第二十步:仿 Android PopupWindow 分享页~

      小菜在学习 Flutter 过程中需要处理一个类似 AndroidPopupWindow 效果的分享弹框页。看似很简单的页面,里面却有很多值得尝试的地方。

      小菜测试时主要用 GridViewBottomSheet 来实现的,当然也可以不用 GridView,小菜简单介绍一下这两组 Widget

GridView

      GridView 我们都很熟悉了,是日常中最常用到的控件之一,小菜前段时间学习了一下 ListView 的基本用法,GridView 的用法基本相同,小菜不再多说,只提醒一个属性,用来设置 GridView item 基本属性。

const SliverGridDelegateWithFixedCrossAxisCount({
   @required this.crossAxisCount, // 每行 item 个数
   this.mainAxisSpacing = 0.0,    // 列间距,即 item 左右间距
   this.crossAxisSpacing = 0.0,   // 行间距,即 item 上下间距
   this.childAspectRatio = 1.0,   // item 宽高比,默认1:1
})
Tips:注意设置 item 个数与列间距的配合,如果太大可能会造成页面展示不全等异常情况。

BottomSheet

      BottomSheet 小菜理解为是从底部向上弹的工作表,主要分为两种:

  1. Persistent 式工作表:类似于一个全新的页面,完全展示 ScaffoldState.showBottomSheet
@override
Widget build(BuildContext context) {
return new Scaffold(
    appBar: new AppBar(
      title: new Text("分享页面"),
    ),
    body: new Center(
      child: new Builder(builder: (BuildContext context) {
        return new FlatButton(
            onPressed: () {
              showBottomSheet(
                  context: context,
                  builder: (BuildContext context) {
                    return _showNomalWid(context);
                  });
            },
            child: new Text("我要分享"),
            color: Colors.blue);
      }),
    ));
}

Widget _showNomalWid(BuildContext context) {
    return new Container(
//        height: 320.0,
//      color: Colors.greenAccent,
      child: new GridView.builder(
        gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 4, mainAxisSpacing: 5.0, childAspectRatio: 1.0),
        itemBuilder: (BuildContext context, int index) {
          return new Column(
            children: <Widget>[
              new Padding(
                padding: EdgeInsets.fromLTRB(0.0, 6.0, 0.0, 6.0),
                child: new Image.asset(
                  'images/${urlItems[index]}', width: 50.0, height: 50.0, fit: BoxFit.fill,
                ),
              ),
              new Text(nameItems[index])
            ],
          );
        },
        itemCount: nameItems.length,
      ),
    );
}

1.1 若用 showBottomSheet 方式开启工作表,同时内容 Widget 不限制宽高,效果为新打开一个页面,点击空白区不会消失,如图:

1.2 若此时设置内容 Widget 宽高,会发现依旧是重新打开一个页面,高度从底向上占据所设置高度,且点击空白区不会消失,如图:

  1. Modal 式工作表:是一个半透明的页面,默认占据屏幕一半 ScaffoldState.showModalBottomSheet
@override
Widget build(BuildContext context) {
return new Scaffold(
    appBar: new AppBar(
      title: new Text("分享页面"),
    ),
    body: new Center(
      child: new Builder(builder: (BuildContext context) {
        return new FlatButton(
            onPressed: () {
              showModalBottomSheet(
                  context: context,
                  builder: (BuildContext context) {
                    return _showNomalWid(context);
                  });
            },
            child: new Text("我要分享"),
            color: Colors.blue);
      }),
    ));
}

2.1 若用 showModalBottomSheet 方式开启工作表,同时内容 Widget 不限制宽高,效果为打开一个半透明页面,默认占据屏幕一半,点击空白区工作表消失,如图:

2.2 若此时设置内容 Widget 宽高,会发现依旧是打开一个半透明页面,高度从底向上占据所设置高度,且点击空白区会消失,如图:

2.3 若此时设置内容 Widget 数据量很多,效果如何呢,这就是小菜选择用 GridView 的原因,在现有宽高内进行可滑动操作即可,如图:

核心源码

      小菜稍稍修饰了一下页面效果,主要源码如下:

import 'package:flutter/material.dart';

class SharePopup extends StatelessWidget {
  List<String> nameItems = <String>[
    '微信', '朋友圈', 'QQ', 'QQ空间', '微博', 'FaceBook', '邮件', '链接'
  ];
  List<String> urlItems = <String>[
    'icon_wechat.png', 'icon_wechat_moments.png', 'icon_qq.png', 'icon_qzone.png',
    'icon_sina.png', 'icon_facebook.png', 'icon_email.png', 'icon_copylink.png'
  ];

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("分享页面"),
        ),
        body: new Center(
          child: new Builder(builder: (BuildContext context) {
            return new FlatButton(
                onPressed: () {
                  showModalBottomSheet(
                      context: context,
                      builder: (BuildContext context) {
                        return _shareWidget(context);
                      });
                },
                child: new Text("我要分享"),
                color: Colors.blue);
          }),
        ));
  }

  Widget _shareWidget(BuildContext context) {
    return new Container(
      height: 250.0,
      child: new Column(
        children: <Widget>[
          new Padding(
            padding: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
            child: new Container(
              height: 190.0,
              child: new GridView.builder(
                gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 4,
                    mainAxisSpacing: 5.0,
                    childAspectRatio: 1.0),
                itemBuilder: (BuildContext context, int index) {
                  return new Column(
                    children: <Widget>[
                      new Padding(
                        padding: EdgeInsets.fromLTRB(0.0, 6.0, 0.0, 6.0),
                        child: new Image.asset( 'images/${urlItems[index]}', width: 50.0, height: 50.0, fit: BoxFit.fill, ) ),
                      new Text(nameItems[index])
                    ],
                  );
                },
                itemCount: nameItems.length,
              ),
            ),
          ),
          new Container( height: 0.5, color: Colors.blueGrey, ),
          new Center( child: new Padding(
              padding: EdgeInsets.fromLTRB(0.0, 8.0, 0.0, 8.0),
              child: new Text( '取  消', style: new TextStyle(fontSize: 18.0, color: Colors.blueGrey), ) ), )
        ],
      ),
    );
  }
}

      小菜刚接触 Flutter 时间不长,还有很多不清楚和不理解的地方,如果有不对的地方还希望多多指教!

目录
相关文章
|
15天前
|
Dart 搜索推荐 API
Flutter & 鸿蒙next版本:自定义对话框与表单验证的动态反馈与错误处理
在现代移动应用开发中,用户体验至关重要。本文探讨了如何在 Flutter 与鸿蒙操作系统(HarmonyOS)中创建自定义对话框,并结合表单验证实现动态反馈与错误处理,提升用户体验。通过自定义对话框和表单验证,开发者可以提供更加丰富和友好的交互体验,同时利用鸿蒙next版本拓展应用的受众范围。
65 1
|
1月前
|
Dart 开发者
flutter:页面整合 (十)
本文档介绍了如何在 Flutter 应用中使用底部导航栏(`BottomNavigationBar`)和侧边栏(`Drawer`),包括简单的使用方法、属性配置、与按钮结合使用、使用图片作为图标、以及如何实现顶部导航。示例代码展示了如何创建包含多个页面的导航栏,并通过 `TabController` 控制器实现页面切换。同时,文档还提供了如何自定义导航栏样式和添加浮动操作按钮(`FloatingActionButton`)的方法。最后,整合了底部导航栏、侧边栏和顶部导航栏的完整示例代码,帮助开发者快速构建具有导航功能的 Flutter 应用界面。
|
4月前
|
UED
Flutter弹窗链-顺序弹出对话框
Flutter弹窗链-顺序弹出对话框
50 0
|
4月前
|
缓存
Flutter仿Boss-6.底部tab切换
Flutter仿Boss-6.底部tab切换
35 0
|
4月前
Flutter-底部弹出框(Widget层级)
文章描述了如何在Flutter中使用DraggableScrollableSheet创建一个底部弹出框,同时保持其可手势滑动关闭。作者遇到问题并提出对原控件进行扩展,以支持头部和列表布局的滑动关闭功能。
180 0
|
5月前
Flutter自定义对话框返回相关问题汇总
Flutter自定义对话框返回相关问题汇总
29 0
|
6月前
Flutter笔记:使用Flutter构建响应式PC客户端/Web页面-案例
Flutter笔记:使用Flutter构建响应式PC客户端/Web页面-案例
328 0
|
6月前
|
开发框架
Flutter自定义对话框返回相关问题汇总
Flutter自定义对话框返回相关问题汇总,详细解释 Flutter是一款流行的移动应用开发框架,它提供了很多内置的对话框,但是有时候我们需要自定义对话框来满足特定需求。在使用自定义对话框时,可能会遇到一些问题,下面是一些常见问题的解答:
Flutter仿写微信导航栏快速实现页面导航
Flutter仿写微信导航栏快速实现页面导航