繁体   English   中英

如何在 Flutter 布局中修复间距

[英]How to fix spacing in Flutter layout

我想创造什么

在此处输入图片说明

我想像这张图片一样创建 Flutter 布局。

  • 有 5 x 6 网格。
  • 最小的小部件是图像的横向正方形。
  • 3 个最小的小部件垂直放置在 1 个网格单元中。
  • 最小小部件的边距比网格的边距窄。

我创造的

在此处输入图片说明

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(scaffoldBackgroundColor: const Color(0xFFEFEFEF)),
      home: Scaffold(
        body: Board(),
        backgroundColor: Colors.white
      ),
      debugShowCheckedModeBanner: false,
    );
  }
}

class Board extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GridView.count(
        primary: false,
        padding: const EdgeInsets.all(2),
        crossAxisSpacing: 0,
        mainAxisSpacing: 0,
        crossAxisCount: 5,
        children: List.generate(30, (index) {
          return Container(
              child: Column(
                children: List.generate(3, (index) {
                  return FractionallySizedBox(
                      widthFactor: 1,
                      heightFactor: 0.3333,
                      child: Image(
                          image: AssetImage("assets/piece_b.png"),
                          fit: BoxFit.contain
                      )
                  );
                })
              )
          );
        })
    );
  }
}

Expanded小部件用于避免BoxConstraints forces an infinite height. 错误。

  • 最小小部件的边距与网格的边距相同。
  • 状态栏中断。
  • 间距很奇怪。

如何在 Flutter 中创建理想的布局?

在此处输入图片说明

import 'dart:math';

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(scaffoldBackgroundColor: const Color(0xFFEFEFEF)),
      home: Scaffold(
        body: SafeArea(
          child: Board(),
        ),
        backgroundColor: Colors.white,
      ),
      debugShowCheckedModeBanner: false,
    );
  }
}

final random = Random();
final data = List.generate(70, (index) => random.nextBool());

class Board extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: BrickColumn(),
    );
  }
}

class BrickColumn extends StatelessWidget {
  const BrickColumn({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    var columnChunks = _splitAtChunks(data, 15);
    List<Widget> children = columnChunks.map((list) {
      var rowChunks = _splitAtChunks(list, 5);
      return Container(
        padding: EdgeInsets.only(bottom: 3),
        child: Column(
          children: rowChunks.map((list) {
            return Container(
              child: BrickRow(bricks: list),
            );
          }).toList(),
        ),
      );
    }).toList();

    return SingleChildScrollView(
      child: Column(
        children: children,
      ),
    );
  }

  List<List<bool>> _splitAtChunks(List<bool> data, int n) {
    var chunks = <List<bool>>[];
    for (var i = 0; i < data.length; i += n) {
      chunks.add(data.sublist(i, i + n > data.length ? data.length : i + n));
    }
    return chunks;
  }
}

class BrickRow extends StatelessWidget {
  const BrickRow({Key key, this.bricks})
      : assert(bricks != null),
        assert(bricks.length == 5),
        super(key: key);

  final List<bool> bricks;

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 2),
        child: Row(
          children: bricks
              .map(
                (isDark) => Expanded(
                    child: Padding(
                  padding: const EdgeInsets.all(2.0),
                  child: Brick(isDark: isDark),
                )),
              )
              .toList(),
        ),
      ),
    );
  }
}

class Brick extends StatelessWidget {
  const Brick({Key key, this.isDark}) : super(key: key);

  final bool isDark;

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (context, constraints) {
      return Container(
        height: constraints.maxWidth / 3,
        decoration: BoxDecoration(
          color: isDark ? Colors.black : Colors.black12,
          borderRadius: BorderRadius.circular(3),
          border: isDark
              ? null
              : Border.all(
                  width: 1.0,
                  color: Colors.black87,
                ),
        ),
      );
    });
  }
}

我跟着Kherel的回答。

最后我做到了。

在此处输入图片说明

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        body: SafeArea(
          child: Center(
            child: Board()
          )
        )
      ),
      debugShowCheckedModeBanner: false,
    );
  }
}

class Board extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    double deviceWidth = MediaQuery.of(context).size.width;

    return Container(
      padding: EdgeInsets.only(
        top: deviceWidth * 0.012,
        right: deviceWidth * 0.01,
        bottom: deviceWidth * 0.012,
        left: deviceWidth * 0.01
      ),
      color: const Color(0xFF2e4a78),
      child: SingleChildScrollView(
        child: Column(
          children: List.generate(6, (rowIndex) {
            return Container(
              padding: EdgeInsets.only(
                  top: deviceWidth * 0.01,
                  bottom: deviceWidth * 0.01
              ),
              child: Column(
                children: List.generate(3, (rowIndex) {
                  return Container(
                      child: Row(
                          children: List.generate(5, (columnIndex) {
                            return Expanded(
                                child: Padding(
                                    padding: EdgeInsets.only(
                                        top: deviceWidth * 0.0025,
                                        left: deviceWidth * 0.01,
                                        right: deviceWidth * 0.01,
                                        bottom: deviceWidth * 0.0025
                                    ),
                                    child: LayoutBuilder(builder: (context, constraints) {
                                      return Container(
                                          height: constraints.maxWidth / 3 -
                                              deviceWidth * 0.005,
                                          child: Image(
                                              image: AssetImage("assets/piece_b.png"),
                                              fit: BoxFit.cover
                                          )
                                      );
                                    })
                                )
                            );
                          })
                      )
                  );
                })
              ),
            );
          })
        )
      )
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM