Flutter响应式布局插件flutter_responsive_template的使用

Flutter响应式布局插件flutter_responsive_template的使用

特性

TODO: 公布后端API示例

图片

  • 登录界面 登录界面
  • 桌面主界面 桌面主界面
  • 移动主界面 移动主界面
  • 桌面注册界面 桌面注册界面
  • 移动注册界面 移动注册界面
  • 过滤界面 过滤界面
  • 已选过滤界面 已选过滤界面
  • 移动菜单 移动菜单
  • 用户配置界面 用户配置界面

初始设置

我们使用了flutter_modular包来管理模块。请根据Flutter_Modular的文档进行相应配置。

main函数中,在启动ModularApp之前,实例化FlutterResponsive类。

该插件还使用了bitsdojo_window。请根据文档对windowslinuxmacos目录进行配置,以获得更好的桌面版本效果。

import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:flutter_responsive_template/flutter_responsive.dart';
import 'package:flutter_responsive_template/utils/telas/menus/menu.dart';
import 'package:flutter_responsive_template/utils/telas/menus/menu_espandido.dart';
import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:flutter_responsive_template/constantes.dart';
import 'app/app_module.dart';
import 'app/app_widget.dart';

void main() {
  // 初始化FlutterResponsive
  FlutterResposive(
    descricaosistema: "MEU SISTEMA",
    fundoLoginLateral: "imagens/fundo_login.jpg",
    pathLogo: "imagens/avaliacao.png",
    fundoLoginPrincipal: "imagens/fundo2.jpg",
    pathImageHeader: "imagens/top-header.png",
    menuMobilePrimaryColor: true,
    logoSecundario: Icon(Icons.edit, size: 50),
    infosistema: "Lorem Ipsum is simply dummy text of the",
    menusexpandidos: [
      MenuExpandido(
        label: "Principal",
        indexMenu: 0,
        iconMobile: Icons.desktop_windows,
        menus: [
          Menu(
            label: "Home",
            icon: Icons.home,
            rota: "/home",
            mapeado: false,
          ),
          Menu(
            label: "Home 2",
            icon: Icons.home_filled,
            rota: "/home2",
            mapeado: false,
          ),
        ],
      ),
    ],
  );

  // 启动应用
  runApp(
    ModularApp(
      module: AppModule(),
      child: AppWidget(),
    ),
  );

  // 如果是桌面端,则初始化窗口大小等属性
  if (isDesktop) {
    doWhenWindowReady(() {
      const initialSize = Size(900, 700);
      appWindow.minSize = Size(300, 500);
      appWindow.size = initialSize;
      appWindow.alignment = Alignment.center;
      appWindow.show();
    });
  }
}

AppWidget

可以在AppWidget中自定义主题样式。

import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

class AppWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: '示例',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primaryColor: Colors.deepOrange,
        iconTheme: IconThemeData(color: Colors.white),
        dataTableTheme: DataTableThemeData(
          dividerThickness: 1,
          headingTextStyle: TextStyle(color: Colors.white),
          headingRowHeight: 30,
          headingRowColor: MaterialStatePropertyAll(
            Colors.deepOrange.withOpacity(0.8),
          ),
        ),
        checkboxTheme: CheckboxThemeData(
          checkColor: MaterialStatePropertyAll(Colors.blue),
        ),
        colorScheme: ColorScheme.light(
          primary: Colors.red,
          secondary: Colors.brown.shade900,
          onPrimary: Colors.white,
          onSecondary: Colors.white,
        ),
      ),
      routeInformationParser: Modular.routeInformationParser,
      routerDelegate: Modular.routerDelegate,
      localizationsDelegates: GlobalMaterialLocalizations.delegates,
      supportedLocales: [const Locale('pt', 'BR')],
    );
  }
}

AppController

创建一个继承自IAppController的类,用作AppModule的绑定。

import 'package:flutter_responsive_template/utils/module_base/app_controller.dart';

class AppController extends IAppController {}

AppModule

为了使插件正常工作,必须在AppModule中实例化以下模块,并确保它们具有相同的路由名称。 仅需创建HomeModule。其他模块可从包中导入。

import 'package:example/app/app_controller.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:flutter_responsive_template_template/app/modules/login/login_module.dart';
import 'package:flutter_responsive_template_template/app/modules/usuarios/usuarios_module.dart';
import 'package:flutter_responsive_template_template/app/modules/perfis/perfis_module.dart';
import 'package:flutter_responsive_template_template/utils/rotas/rota_modal.dart';
import 'package:flutter_responsive_template_template/utils/filtros/herdados/filtro_usuarios.dart';
import 'package:flutter_responsive_template_template/utils/filtros/herdados/filtro_descricao.dart';
import 'modules/home/home_module.dart';

class AppModule extends Module {
  @override
  final List<Bind> binds = [Bind.lazySingleton((i) => AppController())];

  @override
  final List<ModularRoute> routes = [
    ModuleRoute(
      Modular.initialRoute,
      module: LoginModule(),
      transition: TransitionType.noTransition,
    ),
    ModuleRoute(
      "/home",
      module: HomeModule(),
      transition: TransitionType.noTransition,
    ),
    ModuleRoute(
      "/usuario",
      module: UsuariosModule(),
      transition: TransitionType.fadeIn,
    ),
    ModuleRoute(
      "/perfis",
      module: PerfisModule(),
      transition: TransitionType.fadeIn,
    ),
    RotaModal(
      '/filtrarusuario',
      child: (_, args) => FiltroUsuario(),
    ),
    RotaModal('/filtrardescricao', child: (_, args) => FiltroDescricao())
  ];
}

页面和存储的继承模式(简单无数据表)

  • 页面 必须继承TelaBase类,并指定其存储(继承自StoreBase)。例如,下面是HomePage的示例。对于简单的页面,只需使用title和content参数。
import 'package:example/app/modules/home/home_store.dart';
import 'package:flutter/material.dart';
import 'package:flutter_responsive_template/utils/telas/tela_base.dart';

class HomePage extends TelaBase<HomeStore> {
  HomePage()
      : super(
          title: "Home",
          conteudo: () {
            return Container();
          },
        );
}
  • 存储 必须继承StoreBase。
import 'package:flutter_responsive_template_template/utils/telas/store/store_base.dart';
import 'package:mobx/mobx.dart';

part 'home_store.g.dart';

class HomeStore = HomeStoreBase with _$HomeStore;

abstract class HomeStoreBase extends StoreBase with Store {}

页面、存储和存储库的继承模式(数据表)

为了使用数据表,必须使用以下继承结构:

  • 数据 :用于填充数据表的数据类。默认情况下,类会基于从API获取的JSON中的"id"和"descricao"字段生成列和行。若要更改默认生成,重写"processarRow"方法和get “colunas”。当识别到小设备分辨率时调用get card。默认情况下,生成一个包含"id"和"descricao"的Card。如需其他信息,请重写此方法。例如:
import 'package:flutter_responsive_template_template/utils/telas/datatable/data.dart';
class Aluno extends Dados {}
  • 存储库 :用于与数据API连接的类。此类已实现从API调用CRUD操作(GetID, GetAll, delete, save (编辑和添加))。需要提供API的端点。例如:
class AlunoRepository extends Repository {
  AlunoRepository() : super("aluno");
}
  • 存储库基础 :控制基本CRUD操作的类。dataType参数是一个继承自Dados的类。还需要指定repository。
import 'package:escolas/app/model/aluno.dart';
import 'package:escolas/app/modules/aluno/aluno_repository.dart';
import 'package:flutter_responsive_template_template/utils/telas/store/store_base.dart';
import 'package:mobx/mobx.dart';

part 'aluno_store.g.dart';

class AlunoStore = _AlunoStoreBase with _$AlunoStore;

abstract class _AlunoStoreBase extends StoreBase with Store {
  _AlunoStoreBase() : super(datatype: Aluno(), repository: AlunoRepository());
}
  • 桌面基础 :模型主页面的类。使用Title和Filtros(可选)参数。 注意:过滤器有一个在RotaFiltros类中描述的标准。阅读类中的注释以获得更多细节。
import 'package:escolas/app/modules/aluno/aluno_store.dart';
import 'package:flutter_responsive_template_template/utils/telas/partes_tela/rota_filtros.dart';
import 'package:flutter_responsive_template_template/utils/telas/tela_desktop.dart';

class AlunoPage extends TelaDesktopBase<AlunoStore> {
  AlunoPage()
      : super(title: "学生维护", 
      filtros: [
          RotaFiltros(label: "描述", rota: "filtrardescricao"),
          RotaFiltros(
              label: "出生日期",
              rota: "filtrarnascimento",
          )
        ]
      );
}

页面、存储库和存储的继承模式(CRUD)

创建一个名为Crud的子模块并修改主模块类,如下所示: 注意:子模块的路由应为"/crud"

import 'package:escolas/app/modules/aluno/crud/crud_module.dart';
import 'package:escolas/app/modules/aluno/aluno_page.dart';
import 'package:escolas/app/modules/aluno/aluno_store.dart';
import 'package:flutter_responsive_template_template/utils/filtros/bases/filtro_base.dart';
import 'package:flutter_responsive_template_template/utils/filtros/herdados/filtrar_data.dart';
import 'package:flutter_responsive_template_template/utils/rotas/rota_modal.dart';
import 'package:flutter_modular/flutter_modular.dart';

class AlunoModule extends Module {
  @override
  final List<Bind> binds = [
    Bind.lazySingleton((i) => AlunoStore()),
  ];

  @override
  final List<ModularRoute> routes = [
    // 主页
    ChildRoute('/', child: (_, args) => AlunoPage()),
    // 子模块crud
    ModuleRoute("/crud",
        module: CrudModule(), transition: TransitionType.noTransition),
  ];
}
  • CrudStore :控制CRUD的保存和填充数据的类。注意:可以使用主模块相同的repository或创建特定的。
import 'package:escolas/app/modules/aluno/aluno_repository.dart';
import 'package:flutter_responsive_template_template/utils/telas/store/store_crud_base.dart';
import 'package:mobx/mobx.dart';

part 'crud_store.g.dart';

class CrudStore = _CrudStoreBase with _$CrudStore;

abstract class _CrudStoreBase extends StoreCrudBase with Store {
  _CrudStoreBase() : super(repository: AlunoRepository());
}
  • FormGenerator :生成表单的类。需要指定管理此CRUD的CrudBase。输入是实现了IInput接口的类(Input, InputComboBox, InputLookup, InputFoto, InputInline…)。也可以使用Steps创建表单。使用turples参数,并将inputs留空。
import 'package:escolas/app/modules/aluno/crud/crud_store.dart';
import 'package:flutter_responsive_template/utils/telas/inputs/crud_base.dart';
import 'package:flutter_responsive_template/utils/telas/inputs/input.dart';

class CrudPage extends CrudBase<CrudStore> {
  CrudPage()
      : super(
            inputs: [
              Input(
                name: "id",
                label: "Id",
                isPrimaryKey: true,
              ),
              Input(
                  name: "descricao", label: "学生姓名", obrigatorio: true),
              Input(
                  name: "nascimento",
                  label: "出生日期",
                  obrigatorio: true,
                  inputType: InputType.date),
            ],
            title: "学生",
            height: 600,
            width: 600,
          );
}

更多关于Flutter响应式布局插件flutter_responsive_template的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter响应式布局插件flutter_responsive_template的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用flutter_responsive_template插件来实现响应式布局的示例代码。

首先,确保你的pubspec.yaml文件中已经添加了flutter_responsive_template依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_responsive_template: ^latest_version  # 请替换为最新版本号

然后,运行flutter pub get来获取依赖。

接下来,你可以按照以下步骤使用flutter_responsive_template来实现响应式布局。

1. 引入必要的包

在你的主Dart文件中(通常是main.dart),引入必要的包:

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

2. 创建响应式模板

你可以使用ResponsiveTemplate小部件来创建响应式布局。下面是一个简单的示例:

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Responsive Layout',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ResponsiveTemplate(
        breakpoints: [
          ResponsiveBreakpoint.small(480),
          ResponsiveBreakpoint.medium(768),
          ResponsiveBreakpoint.large(1024),
          ResponsiveBreakpoint.xlarge(1200),
        ],
        builders: {
          ResponsiveSize.small: (context, child) => SmallScreenLayout(),
          ResponsiveSize.medium: (context, child) => MediumScreenLayout(),
          ResponsiveSize.large: (context, child) => LargeScreenLayout(),
          ResponsiveSize.xlarge: (context, child) => XLargeScreenLayout(),
        },
      ),
    );
  }
}

class SmallScreenLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Small Screen Layout'),
      ),
      body: Center(
        child: Text('This is a small screen layout'),
      ),
    );
  }
}

class MediumScreenLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Medium Screen Layout'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text('This is a medium screen layout'),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () {},
            child: Text('Click Me'),
          ),
        ],
      ),
    );
  }
}

class LargeScreenLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Large Screen Layout'),
      ),
      body: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          Text('Left Column'),
          Text('Right Column'),
        ],
      ),
    );
  }
}

class XLargeScreenLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('X-Large Screen Layout'),
      ),
      body: GridView.count(
        crossAxisCount: 3,
        children: List.generate(9, (index) {
          return Center(
            child: Text('Item $index'),
          );
        }),
      ),
    );
  }
}

3. 运行应用

将上述代码保存并运行你的Flutter应用。在不同的屏幕尺寸或模拟器上测试,你会看到根据屏幕尺寸的不同,布局会相应地变化。

这个示例展示了如何使用flutter_responsive_template插件根据屏幕尺寸创建不同的布局。你可以根据需要自定义每个屏幕尺寸下的布局和组件。

回到顶部