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

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

特性

  • 根据设备屏幕大小自适应应用程序内容。
  • 提供适用于移动设备、平板电脑、桌面和电视的自定义小部件。
  • 易于使用且易于集成到现有的Flutter应用中。

开始使用

确保您的机器上已安装Flutter。更多安装信息,请参阅官方Flutter文档

安装

pubspec.yaml文件中添加以下依赖:

dependencies: 
  responsive_mixin_layout: ^1.6.0

然后运行命令 flutter pub get 获取依赖项。

设置

ScreenSizes包装您的materialApp,可以在该组件中全局配置屏幕宽度和高度值。

ScreenSizes(
  child: MaterialApp(
    theme: ThemeApp.of(context),
    navigatorKey: navigatorKey,
    debugShowCheckedModeBanner: false,
  ),
)

使用

这是一个基本示例,展示如何使用Flutter响应式混合布局插件:

class HomePage extends StatelessWidget with ResponsiveMixinLayout {
  const HomePage({super.key});

  @override
  bool get basedOnLayout => true;

  @override
  Widget? desktopLayout(BuildContext context, BoxConstraints constraints) {
    return const Scaffold(
      body: _Page1(),
    );
  }

  @override
  Widget tabletLayout(BuildContext context, BoxConstraints constraints) {
    return Scaffold(
      body: PageView(
        children: const [
          _Page1(),
        ],
      ),
    );
  }
}

您也可以使用ResponsiveLayout

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

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

class MyApp extends StatelessWidget { 
  @override 
  Widget build(BuildContext context) { 
    return ResponsiveLayout( 
      mobile: (context, constraints) { 
        // 移动设备布局
        return Container( 
          color: Colors.red, 
          child: Text('Mobile Layout'), 
        ); 
      }, 
      tablet: (context, constraints) { 
        // 平板设备布局
        return Container( 
          color: Colors.blue, 
          child: Text('Tablet Layout'), 
        ); 
      }, 
      desktop: (context, constraints) { 
        // 桌面设备布局
        return Container( 
          color: Colors.green, 
          child: Text('Desktop Layout'), 
        ); 
      }, 
      tv: (context, constraints) { 
        // 电视设备布局
        return Container( 
          color: Colors.yellow, 
          child: Text('TV Layout'), 
        ); 
      }, 
    ); 
  } 
}

RenderBoxBuilder

一个提供对其子部件的RenderBox访问并触发回调的小部件。

示例用法:

RenderBoxBuilder(
  child: YourWidget(),
  onRenderBox: (context, renderBox) {
    // 处理RenderBox
    print('RenderBox size: ${renderBox.size}');
  },
)

BoxSizeListener

一个监听其子部件尺寸变化并触发回调的小部件。

示例用法:

BoxSizeListener(
  child: YourWidget(),
  onSizeChanged: () {
    // 处理尺寸变化
    print('Size changed');
  },
)

ScreenSizeListener

一个监听屏幕尺寸变化并触发回调的小部件。

示例用法:

ScreenSizeListener(
  child: YourWidget(),
  onSizeChanged: (newSize) {
    // 处理屏幕尺寸变化
    print('Screen size changed: $newSize');
  },
)

TextScalerBuilder

一个基于屏幕大小提供自定义文本缩放因子的小部件。

示例用法:

TextScalerBuilder(
  child: YourWidget(),
  scaler: (context, media) {
    // 根据屏幕大小计算缩放因子
    return media.size.width / 400.0;
  },
)

DoubleExtension

double类提供额外实用方法的扩展。

方法:

  • clampInverted(double lowerLimit, double upperLimit): 返回在范围 [lowerLimit]-[upperLimit] 中但反转后的double。
  • clampMapRanged({bool invert = false, required double minRange, required double maxRange, required double minValue, required double maxValue}): 将值从一个范围映射到另一个范围,并可选择性地反转结果。

示例用法:

void main() {
  double value = 5.0;
  double clampedInverted = value.clampInverted(1.0, 10.0);
  double mappedValue = value.clampMapRanged(
    minRange: 0.0,
    maxRange: 10.0,
    minValue: 100.0,
    maxValue: 200.0,
  );

  print('Clamped Inverted: $clampedInverted');
  print('Mapped Value: $mappedValue');
}

随机整数小部件

使用RenderRandomInt生成指定范围内的随机整数并在您的小部件树中使用它。

示例用法:

import 'package:random_widgets_package/random_widgets_package.dart';

RenderRandomInt(
  range: 100,
  builder: (context, randomInt) {
    return Text('Random Integer: $randomInt');
  },
);

随机双精度小部件

使用RenderRandomDouble生成指定范围内的随机双精度值并在您的小部件树中使用它。

示例用法:

import 'package:random_widgets_package/random_widgets_package.dart';

RenderRandomDouble(
  range: 100.0,
  builder: (context, randomDouble) {
    return Text('Random Double: $randomDouble');
  },
);

随机布尔小部件

使用RenderRandomBool生成随机布尔值并在您的小部件树中使用它。

示例用法:

import 'package:random_widgets_package/random_widgets_package.dart';

RenderRandomBool(
  builder: (context, randomBool) {
    return Text('Random Boolean: $randomBool');
  },
);

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

1 回复

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


当然,下面是一个关于如何在Flutter中使用responsive_mixin_layout插件来实现响应式布局的示例代码。这个插件允许你根据屏幕尺寸和方向来动态调整布局。

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

dependencies:
  flutter:
    sdk: flutter
  responsive_mixin_layout: ^x.y.z  # 请使用最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以使用ResponsiveMixinResponsiveLayoutBuilder来创建响应式布局。以下是一个示例代码:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Responsive Layout Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ResponsiveScaffold(
        appBar: AppBar(
          title: Text('Responsive Layout Demo'),
        ),
        body: ResponsiveLayoutBuilder(
          builder: (context, sizingInformation) {
            if (sizingInformation.deviceType == DeviceType.mobile) {
              return MobileLayout(sizingInformation);
            } else if (sizingInformation.deviceType == DeviceType.tablet) {
              return TabletLayout(sizingInformation);
            } else {
              return DesktopLayout(sizingInformation);
            }
          },
        ),
      ),
    );
  }
}

class MobileLayout extends StatelessWidget {
  final SizingInformation sizingInformation;

  MobileLayout(this.sizingInformation);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(sizingInformation.scale(16)),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text('This is Mobile Layout', style: TextStyle(fontSize: sizingInformation.scale(24))),
          SizedBox(height: sizingInformation.scale(20)),
          ElevatedButton(
            onPressed: () {},
            child: Text('Click Me', style: TextStyle(fontSize: sizingInformation.scale(18))),
          ),
        ],
      ),
    );
  }
}

class TabletLayout extends StatelessWidget {
  final SizingInformation sizingInformation;

  TabletLayout(this.sizingInformation);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(sizingInformation.scale(24)),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Expanded(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text('This is Tablet Layout', style: TextStyle(fontSize: sizingInformation.scale(32))),
                SizedBox(height: sizingInformation.scale(30)),
                ElevatedButton(
                  onPressed: () {},
                  child: Text('Click Me', style: TextStyle(fontSize: sizingInformation.scale(24))),
                ),
              ],
            ),
          ),
          Expanded(
            child: Placeholder(), // 你可以在这里添加其他组件
          ),
        ],
      ),
    );
  }
}

class DesktopLayout extends StatelessWidget {
  final SizingInformation sizingInformation;

  DesktopLayout(this.sizingInformation);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(sizingInformation.scale(32)),
      child: GridView.count(
        crossAxisCount: 2,
        childAspectRatio: 1.0,
        children: <Widget>[
          Card(
            child: Padding(
              padding: EdgeInsets.all(sizingInformation.scale(16)),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('Card 1', style: TextStyle(fontSize: sizingInformation.scale(24))),
                  SizedBox(height: sizingInformation.scale(10)),
                  ElevatedButton(
                    onPressed: () {},
                    child: Text('Click Me', style: TextStyle(fontSize: sizingInformation.scale(18))),
                  ),
                ],
              ),
            ),
          ),
          Card(
            child: Padding(
              padding: EdgeInsets.all(sizingInformation.scale(16)),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('Card 2', style: TextStyle(fontSize: sizingInformation.scale(24))),
                  SizedBox(height: sizingInformation.scale(10)),
                  ElevatedButton(
                    onPressed: () {},
                    child: Text('Click Me', style: TextStyle(fontSize: sizingInformation.scale(18))),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

在这个示例中,我们创建了一个MyApp应用,它使用ResponsiveScaffoldResponsiveLayoutBuilder来根据不同的设备类型(手机、平板、桌面)来显示不同的布局。sizingInformation对象提供了关于当前设备的信息,包括屏幕尺寸和方向,以及一个scale方法来帮助你根据屏幕尺寸动态调整组件的大小。

你可以根据需要进一步自定义这些布局,并添加更多的组件和逻辑。

回到顶部