flutter_responsive

此插件提供了一种简单高效的方式来处理 Flutter 应用程序的响应式布局,适用于移动、桌面和 Web 应用。它允许您的布局根据父级元素的尺寸自适应地调整和包装小部件(Container、Rows、Columns 和 RichText)。

许可

本项目遵循 GNU General Public License V3,这意味着您可以根据需要修改整个项目,但需要将您的改进分享回社区。

要分享您的改进,请先 Fork 本项目,进行修改,然后提交一个 Pull Request。并且,即使在开始修改之前,也不要忘记在“Issues”页面分享您的想法和需求。

重要提示

  • 此插件基于 Bootstrap Web Project,但尚未实现其所有功能(目前还没有)。
  • 列的响应性是基于其最近的父级小部件尺寸,而不是屏幕尺寸,这一点与 Bootstrap 不同。
  • 所有小部件都包含边距、内边距、宽度、高度(最大和最小边界),类似于 HTML 的 div 元素。
  • 欢迎自由改进和修改本项目。

如何使用

将以下依赖项添加到您的 pubspec.yaml 文件中。

dependencies:
  flutter_responsive: ^0.0.4 #Please, ensure to use the most updated version

在您的 .dart 文件中添加引用

import 'package:flutter_responsive/flutter_responsive.dart';

按需使用 ResponsiveContainerResponsiveRowResponsiveColResponsiveText 小部件。

屏幕尺寸

此插件基于 Bootstrap Web 项目,将屏幕划分为 12 列,并考虑了 7 种屏幕尺寸。

  • US - 超小屏幕 - 0px 到 309px
  • XS - 特小屏幕 - 310px 到 575px
  • SM - 小屏幕 - 576px 到 767px
  • MD - 中等屏幕 - 768px 到 991px
  • LG - 大屏幕 - 992px 到 1199px
  • XL - 超大屏幕 - 1200px 到 1999px
  • UL - 极致大屏 - 2000px 及以上

example_1
example_2
example_3
example_4

个性化边界(可选)

所有边界都可以根据您的需求进行个性化设置,通过修改 ResponsiveScreen 类中的 limit Hashmap 来实现。

/* Map<String, double> */
ResponsiveScreen.limits = {
    'us': 0.00,
    // Smart watches
    'xs': 310.00,
    // Small phones (5c)
    'sm': 576.00,
    // Medium phones
    'md': 768.00,
    // Large phones (iPhone X)
    'lg': 992.00,
    // Tablets
    'xl': 1200.00,
    // Laptops
    'ul': 2000.00,
    // Desktops and TVs 4K
  };

网格使用

此插件包含 3 个主要的网格元素。

  • ResponsiveContainer: 所有页面元素的容器,例如 Rows 和 Columns,用于集中内容并限制最大宽度。
ResponsiveContainer(

  // Determines the container's limit size
  widthLimit: ResponsiveScreen.limits['lg'],
  margin: EdgeInsets.symmetric(horizontal: 10),
  
  children: <Widget>[
  
    ResponsiveRow(),
    ResponsiveRow(),
    ResponsiveRow(),
    
  ]
)
  • ResponsiveRow: 包含多个列或任何其他小部件的容器。
    注意:不需要将内部小部件包装在 ResponsiveCol 对象中。
ResponsiveRow(

  margin: EdgeInsets.only(top: 20, bottom: 5),
  
  children: <Widget>[
  
    ResponsiveCol(),
    ResponsiveCol(),
    ResponsiveCol(),
    
    Text('It´s fine to use another widget directly inside a ResponsiveRow', style: ResponsiveTypography.q)
  ]
),
  • ResponsiveCol
ResponsiveCol(
  margin: EdgeInsets.all(10),
  padding: EdgeInsets.all(10),
  backgroundColor: Colors.blue,
  gridSizes: {
      'xs' : 4,
      'sm' : 3,
      'lg' : 2,
      'xl' : 1,
  },
  children: [
      Text('Lorem ipsum dolor sit amet, consectetur adipiscing elit', style: ResponsiveTypography.h2)
  ]
)

完整示例

import 'package:flutter/material.dart';
import 'package:flutter_responsive/flutter_responsive.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePage createState() => _HomePage();
}

class _HomePage extends State<HomePage> {

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    /*create 12 columns*/
    List<Widget> responsiveGridExample =

      /*repeat 12 times*/
      List<int>.generate(12, (index) => index).map((colIndex) =>
          ResponsiveCol(
              padding: EdgeInsets.all(10),
              backgroundColor: Colors.blue,
              gridSizes: {
                'xs' : 4,
                'sm' : 3,
                'lg' : 2,
                'xl' : 1,
              },
              children: [
                Text('Lorem ipsum dolor sit amet, consectetur adipiscing elit')
              ]
          )
      ).toList();

    MediaQueryData mediaQuery = MediaQuery.of(context);

    return Scaffold(
        appBar: AppBar(
          title: const Text('Home', overflow: TextOverflow.ellipsis),
        ),
        body: Container(
          color: Color(0xFFCCCCCC),
          child: ListView(
            children: <Widget>[
              ResponsiveContainer(
                margin: EdgeInsets.symmetric(vertical: 10),
                padding: EdgeInsets.symmetric(horizontal: 10),
                backgroundColor: Colors.white,
                widthLimit: mediaQuery.size.width * 0.95,
                children: <Widget>[
                  ResponsiveRow(
                    margin: EdgeInsets.symmetric(vertical: 10),
                    children: <Widget>[

                      ResponsiveCol(
                          padding: EdgeInsets.all(10),
                          margin: EdgeInsets.only(bottom: 20),
                          backgroundColor: Colors.blueGrey,
                          children: [
                            Text('Flutter Responsive Layout', style: ResponsiveTypography.h4.merge(TextStyle(color: Colors.white)))
                          ]
                      ),
                    ]
                  ),
                  ResponsiveRow(
                    margin: EdgeInsets.symmetric(vertical: 10),
                    children: <Widget>[

                      // By default, the column occupies the entire row, always
                      ResponsiveCol(
                        children: [
                          ResponsiveText(
                            shrinkToFit: true,
                            padding: EdgeInsets.only(bottom: 20),
                            stylesheet: {
                              'h3': ResponsiveStylesheet(
                                  textStyle: TextStyle(color: Theme.of(context).primaryColor),
                                  displayStyle: DisplayStyle.block
                              ),
                              'h6': ResponsiveStylesheet(
                                  textStyle: TextStyle(color: Theme.of(context).primaryColor),
                                  displayStyle: DisplayStyle.block
                              )
                            },
                            margin: EdgeInsets.symmetric(horizontal: 10, vertical: 20),
                            text:
                            '<div>'
                                '<h3>Responsive Layouts</h3><h6>for <i>Flutter</i></h6>'
                                '<br><br>'
                                '<p>This <b>RichText</b> was easily produced and personalized using pure HTML</p>'
                                '<p>Bellow there is an example of 12 columns, wich changes the amount of each line depending of his father´s widget size.</p>'
                            '</div>',
                          )
                        ]
                      )

                    ]..addAll(
                        responsiveGridExample
                    )
                  )
                ],
              )
            ],
          ),
        )
    );
  }
}

最终结果

example_9

如何运行插件示例

本项目是 Flutter 的起点
插件包,
一个专门的包,包含特定于平台的实现代码
Android 和/或 iOS。

如需获取 Flutter 入门帮助,请参阅我们的
在线文档,其中提供教程,
示例、移动开发指南和完整的 API 参考。

要运行完整的示例应用程序,其中包含性能和用例测试,请按照以下步骤操作:

  • 使用 Github Desktop 或您偏好的任何其他 Git 程序将此项目克隆到您的本地机器。
  • 下载 Android Studio 和最新的 Flutter SDK 到您的本地机器。正确配置它们,例如 此处的文章。
  • 运行 flutter pub get 来更新所有依赖项。
  • 在模拟器或真实设备上调试 example/lib/main.dart 文件或 test 文件夹中的任何单元测试用例。
  • 要正确运行性能测试,请使用 flutter run --release 运行应用程序。

GitHub

https://github.com/rafaelsetragni/flutter_responsive