點燈坊

失くすものさえない今が強くなるチャンスよ

MediaQuery 動態設定 Row 的 Gap

Sam Xiao's Avatar 2024-11-03

Pixel Overflow 是 Flutter 開發中常遇到的問題,透過由 MediaQuery 取得裝置長寬,可動態設定 Row 的 Gap 避免 Pixel Overflow。

Version

Flutter 3.24

Flutter

gap01

  • Android 與 iOS 都成功使用 MediaQuery 動態設定 Row 的 gap

MediaQuery

import 'package:flutter/material.dart';

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

  
  State<Home> createState() => _Home();
}

class _Home extends State<Home> {
  var _deviceWidth = 0.0;

  
  Widget build(BuildContext context) {
    _deviceWidth = MediaQuery.of(context).size.width;

    var appBar = AppBar(
      title: const Text('Responsive Row Gap'),
    );

    var container1 = Container(
      width: 100,
      height: 100,
      color: Colors.blue,
    );

    var gap = SizedBox(
      width: _deviceWidth * 0.1,
    );

    var container2 = Container(
      width: 100,
      height: 100,
      color: Colors.green,
    );

    return Scaffold(
      appBar: appBar,
      body: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            container1,
            gap,
            container2,
          ],
        ),
      ),
    );
  }
}

Line 10

class _Home extends State<Home> {
  var _deviceWidth = 0.0;
}
  • _deviceWidth:定義 _deviceWidth 為 field,如此所有地方都可直接存取

Line 14

Widget build(BuildContext context) {
  _deviceWidth = MediaQuery.of(context).size.width;
  • _deviceWidth:在 build() 內由 context 取得裝置寬度

Line 40

child: Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
   container1,
   gap,
   container2,
  ],
),
  • 使用 Row 水平排列兩個 Container,之間有 gap

Line 20

var gap = SizedBox(
  width: _deviceWidth * 0.1,
);
  • Row 的 gap 實際上是使用 SizedBox 實現
  • SizedBox 的 width 並不是固定 pixel,而是使用 deviceWidth比例 的方式取得,如此可確保在更小的裝置會有更小的 gap

Conclusion

  • 通常 designer 會先依據某一個裝置設計,開發時可使用與 designer 相同的 simulator 開發,先寫死 pixel 切版 ,待切版成功後,再使用 MediaQuery 取得裝置的 width,以 比例 的方式設定 gap,如此可確保更小的裝置也不會 Pixel Overflow
  • 可將 deviceWidth 定義成 field,如此所有地方都可直接存取