Flutter布局管理插件layout的使用

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

Flutter布局管理插件layout的使用

Layout

pub package Layout Demo

根据Material Design指南,Layout鼓励跨平台、环境和屏幕尺寸的一致性,通过使用统一的元素和间距。

安装 Install

按照这里的说明进行安装。

入门 Getting Started

该包旨在以简单和一致的方式提供实现响应式布局所需的工具。 如果您想详细了解Material Design中的布局,我推荐您访问官方网站

让我们开始吧!

所有内容都从Layout小部件开始。通常添加在小部件树的顶部,但您可以根据需要将其放置在任何位置。它使用其小部件约束来计算断点、列、边距和间隔。

  @override
  Widget build(BuildContext context) {
    return Layout(
      child: MaterialApp(
        // ...
      ),
    );
  }

断点 Breakpoints

断点是预定义屏幕大小范围,具有特定的布局要求。在给定的断点范围内,布局会调整以适应屏幕大小和方向。

每个断点范围确定每种显示大小的列数以及建议的边距和间隔。

默认情况下,断点定义如下:

  • xs: 0 – 599
  • sm: 600 – 1023
  • md: 1024 – 1439
  • lg: 1440 – 1919
  • xl: 1920 +
 @override
 Widget build(BuildContext context) {
   if(context.breakpoint > LayoutBreakpoint.md)
     return TabletView();
   else
     return MobileView();
 }

布局值 LayoutValues

布局值相对于屏幕宽度。这样可以定义响应式变量,在需要时重用它们并应用它们。

final double padding = context.layout.value(xs: 0.0, sm: 12.0, md: 24.0, lg: 32.0, xl: 48.0);

最重要的布局值是与断点相关的那些。这些是最常见和有用的,因为您可以为不同的断点大小定义一个值。如果未提供断点,则其值将对应于第一个前一个/较小的断点。

final double padding = context.layout.value(
     xs: 0.0,  // sm value will be like xs 0.0
     md: 24.0, // lg value will be like md 24.0
     xl: 48.0
);

布局值可以在应用程序的不同部分甚至不同的Layout小部件中重用。为此,它们需要创建为

final displaySidebar = LayoutValue(xs: false, md: true);

final horizontalMargin = LayoutValue.builder((layout) {
    double margin = layout.width >= 500 ? 24.0 : 16.0;
    margin += 8.0 * layout.visualDensity.horizontal;
    return EdgeInsets.symmetric(horizontal: margin);
});

然后可以在树中有Layout的任何小部件中使用:

return Column(
  children: [
    Padding(
      padding: horizontalMargin.resolve(context),
      child:child,
    ),
    if(displaySidebar.resolve(context))
      SideBar(),
    ),
  ],
);

您还可以创建相对于布局宽度的值。

final displaySidebar = LayoutValue.builder((layout) => layout.width > 600);

边距 Margins

边距是内容与屏幕左右边缘之间的空间。

  @override
  Widget build(BuildContext context) {
    return Margin(
      child: Text('This text'),
    );
  }

边距宽度是在每个断点范围内定义的固定值。为了更好地适应屏幕,边距宽度可以在不同的断点处更改。较大的屏幕更适合较宽的边距,因为它们在内容周围创建更多的空白。

默认情况下,边距值是Material Design指南中的值。宽度小于720dp的屏幕为16dp,更大的屏幕为24dp。您可以通过提供边距参数随时覆盖这些值。

流动边距 Fluid Margins

有时您希望有一个在不同屏幕尺寸上保持不变的固定宽度。

  @override
  Widget build(BuildContext context) {
    return FluidMargin(
      child: Text('This text'),
    );
  }

流动边距动态更新以保持其内部子项的固定大小。这些固定大小默认是Material Design指南中的值,但也可以轻松自定义。

自适应构建器 AdaptiveBuilder

允许轻松构建响应式布局的小部件

  @override
  Widget build(BuildContext context) {
    return AdaptiveBuilder(
      xs: (context) => LayoutWithBottomNavigationBar(),
      lg: (context) => LayoutWithTrailingNavigationBar(),
    );
  }

或对于更复杂的情况

  @override
  Widget build(BuildContext context) {
    return  AdaptiveBuilder.builder(
      builder: (context, layout, child) {
        if (layout.breakpoint < LayoutBreakpoint.lg) {
          return LayoutWithBottomNavigationBar(child: child);
        } else {
          return LayoutWithTrailingNavigationBar(child: child);
        }
      },
      child: child,
    );
  }

示例代码 Example Code

以下是完整的示例代码,展示了如何使用layout包创建一个包含响应式布局的应用程序。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Layout(
      child: MaterialApp(
        title: 'Flutter Demo',
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          appBarTheme: AppBarTheme(
            color: Colors.white,
          ),
          scaffoldBackgroundColor: Colors.grey[200],
          primarySwatch: Colors.blue,
        ),
        home: MyHomePage(title: 'Layout'),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final String title;

  MyHomePage({required this.title});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: AdaptiveBuilder(
        xs: (context) => Center(child: Text('Mobile View')),
        md: (context) => Center(child: Text('Tablet View')),
        lg: (context) => Center(child: Text('Desktop View')),
      ),
    );
  }
}

这个示例展示了如何使用LayoutAdaptiveBuilder来创建一个简单的响应式布局,根据屏幕大小显示不同的内容。


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

1 回复

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


在Flutter中,布局管理是通过一系列强大的Widget来实现的,这些Widget帮助开发者创建复杂且响应式的用户界面。虽然没有一个名为“layout”的官方插件(因为布局功能已经集成在Flutter的核心框架中),但我们可以使用Flutter内置的布局Widget来实现各种布局需求。

下面是一些常用的布局Widget及其使用示例:

1. Container

Container是最基本的布局Widget,用于包装其他Widget并提供一些基本的布局和装饰属性,如padding、margin、color等。

Container(
  color: Colors.blue,
  padding: EdgeInsets.all(16.0),
  child: Text('Hello, World!', style: TextStyle(color: Colors.white)),
);

2. Column

Column用于垂直排列子Widget。

Column(
  children: <Widget>[
    Text('First Line'),
    Text('Second Line'),
    Text('Third Line'),
  ],
);

3. Row

Row用于水平排列子Widget。

Row(
  children: <Widget>[
    Text('Left Text'),
    Spacer(), // 用于填充空间
    Text('Right Text'),
  ],
);

4. Stack

Stack允许将子Widget堆叠在一起,通常与PositionedWidget一起使用来定位子Widget。

Stack(
  children: <Widget>[
    Text('Bottom Text'),
    Positioned(
      top: 10,
      right: 10,
      child: Text('Top Right Text'),
    ),
  ],
);

5. GridView

GridView用于创建一个网格布局。

GridView.count(
  crossAxisCount: 3, // 每行3个元素
  childAspectRatio: 1.0, // 子元素的宽高比
  children: List.generate(9, (index) {
    return Center(
      child: Text('Grid Item $index'),
    );
  }),
);

6. ListView

ListView用于创建一个垂直滚动的列表。

ListView(
  children: <Widget>[
    ListTile(
      leading: Icon(Icons.map),
      title: Text('Map'),
    ),
    ListTile(
      leading: Icon(Icons.photo),
      title: Text('Album'),
    ),
    ListTile(
      leading: Icon(Icons.folder),
      title: Text('Folder'),
    ),
  ],
);

7. Flex

Flex是一个灵活的布局Widget,可以水平或垂直排列子Widget,并允许设置每个子Widget的伸缩因子(flex factor)。

Flex(
  direction: Axis.horizontal, // 水平排列
  children: <Widget>[
    Flexible(
      flex: 2, // 占据2倍的剩余空间
      child: Text('Flexible Space 2'),
    ),
    Flexible(
      flex: 1, // 占据1倍的剩余空间
      child: Text('Flexible Space 1'),
    ),
  ],
);

8. Positioned

Positioned通常与Stack一起使用,用于指定子Widget在Stack中的精确位置。

Stack(
  children: <Widget>[
    Text('Base Text'),
    Positioned(
      top: 20,
      left: 20,
      child: Text('Positioned Text'),
    ),
  ],
);

这些示例展示了Flutter中一些基本的布局Widget的用法。通过组合这些Widget,你可以创建出复杂且响应式的用户界面。如果你有更具体的布局需求,可以进一步组合和嵌套这些Widget来实现。

回到顶部