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

发布于 1周前 作者 gougou168 来自 Flutter

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

特性

  • 根据Material Design实现自定义断点检测当前屏幕大小。
  • 支持Material 2和Material 3设计系统。

使用方法

请查看示例代码以了解如何使用adaptive_breakpoints_freezed插件。

AdaptiveBuilder(
    builder: (context, entry, constraints) {
      return entry.type.when(
        xs: () {
          return Text("xs $_counter");
        },
        s: () {
          return Text("s $_counter");
        },
        m: () {
          return Text("m $_counter");
        },
        l: () {
          return Text("l $_counter");
        },
        xl: () {
          return Text("xl $_counter");
        },
      );
    },
)
context.adaptive.maybeWhen(
    l: () {
        print("large");
    },
    orElse: () {
        print("other sizes")
    }
)

示例代码

example/lib/main.dart文件中:

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Adaptive"),
      ),
      body: AdaptiveBuilder(
        builder: (context, entry, constraints) {
          return entry.type.when(
            xs: () {
              return Text(
                "xs $_counter",
                style: const TextStyle(color: Colors.black, fontSize: 18),
              );
            },
            s: () {
              return Text(
                "s $_counter",
                style: const TextStyle(color: Colors.black, fontSize: 18),
              );
            },
            m: () {
              return Text(
                "m $_counter",
                style: const TextStyle(color: Colors.black, fontSize: 18),
              );
            },
            l: () {
              return Text(
                "l $_counter",
                style: const TextStyle(color: Colors.black, fontSize: 18),
              );
            },
            xl: () {
              return Text(
                "xl $_counter",
                style: const TextStyle(color: Colors.black, fontSize: 18),
              );
            },
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          context.adaptive.whenDevice(
            mobile: () {
              _counter++;
            },
            tablet: () {
              _counter += 2;
            },
            desktop: () {
              _counter += 4;
            },
          );
        },
        tooltip: 'Increment',
        child: context.adaptive.whenDevice(
          mobile: () => const Icon(Icons.screenshot),
          tablet: () => const Icon(Icons.tablet),
          desktop: () => const Icon(Icons.desktop_mac),
        ),
      ),
    );
  }
}

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

1 回复

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


当然,以下是如何在Flutter项目中使用adaptive_breakpoints_freezed插件来实现响应式布局的示例代码。这个插件通过定义断点(breakpoints)来帮助你创建自适应的布局。

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

dependencies:
  flutter:
    sdk: flutter
  adaptive_breakpoints_freezed: ^版本号  # 替换为当前最新版本号

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

接下来,我们需要定义一些断点。使用adaptive_breakpoints_freezed,你可以通过定义枚举类并使用@freezed注解来实现这一点。确保你也添加了freezedjson_annotation依赖到你的pubspec.yaml文件中,因为adaptive_breakpoints_freezed依赖于它们。

dependencies:
  freezed_annotation: ^版本号
  json_annotation: ^版本号
dev_dependencies:
  build_runner: ^版本号
  freezed: ^版本号

然后创建一个新的Dart文件,例如breakpoints.dart,来定义你的断点:

import 'package:adaptive_breakpoints_freezed/adaptive_breakpoints_freezed.dart';
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'breakpoints.freezed.dart';

@freezed
class MyBreakpoints with _$MyBreakpoints {
  const factory MyBreakpoints({
    required double mobile,
    required double tablet,
    required double desktop,
  }) = _MyBreakpoints;

  factory MyBreakpoints.fromSize(Size size) {
    return MyBreakpoints(
      mobile: 600.0,
      tablet: 960.0,
      desktop: 1200.0,
    ).copyWith(
      // 使用屏幕尺寸动态调整断点(可选)
      // mobile: size.width < 600 ? size.width : 600.0,
      // tablet: size.width < 960 ? (size.width >= 600 ? size.width : 600.0) : 960.0,
      // desktop: size.width >= 1200 ? size.width : 1200.0,
    );
  }
}

生成breakpoints.freezed.dart文件:

flutter pub run build_runner build

现在,你可以在主应用程序中使用这些断点来创建响应式布局。例如,在main.dart中:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ResponsiveScaffold(
        breakpoints: MyBreakpoints.fromSize(MediaQuery.of(context).size),
        builder: (context, size, breakpoint) {
          return Scaffold(
            appBar: AppBar(title: Text('Responsive Layout')),
            body: LayoutBuilder(
              builder: (context, constraints) {
                if (breakpoint.mobile) {
                  return Center(child: Text('Mobile Layout'));
                } else if (breakpoint.tablet) {
                  return Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text('Tablet Layout'),
                      SizedBox(height: 20),
                      Text('More content...'),
                    ],
                  );
                } else {
                  return Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text('Desktop Layout'),
                      SizedBox(width: 20),
                      Text('Even more content...'),
                    ],
                  );
                }
              },
            ),
          );
        },
      ),
    );
  }
}

// 自定义ResponsiveScaffold来根据断点构建UI
class ResponsiveScaffold extends StatelessWidget {
  final MyBreakpoints breakpoints;
  final Widget Function(BuildContext, Size, MyBreakpoints) builder;

  const ResponsiveScaffold({
    Key? key,
    required this.breakpoints,
    required this.builder,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final breakpoint = _getBreakpoint(size);
    return builder(context, size, breakpoint);
  }

  MyBreakpoints _getBreakpoint(Size size) {
    return breakpoints.copyWith(
      mobile: size.width <= breakpoints.mobile,
      tablet: size.width > breakpoints.mobile && size.width <= breakpoints.tablet,
      desktop: size.width > breakpoints.tablet,
    );
  }
}

extension BreakpointExtension on MyBreakpoints {
  bool get mobile => this.mobile!;
  bool get tablet => this.tablet!;
  bool get desktop => this.desktop!;
}

在这个示例中,我们创建了一个ResponsiveScaffold自定义小部件,它根据屏幕尺寸应用不同的布局。断点是通过MyBreakpoints类定义的,该类使用adaptive_breakpoints_freezed提供的机制来确保不可变性。

注意,这里的ResponsiveScaffold和断点扩展是为了演示目的而编写的,你可以根据自己的需求进行调整。

希望这个示例能帮助你理解如何在Flutter项目中使用adaptive_breakpoints_freezed来实现响应式布局。

回到顶部