Flutter 即學即用系列博客——07 RenderFlex overflowed 引發的思考

来源:https://www.cnblogs.com/nesger/archive/2019/03/10/10506422.html
-Advertisement-
Play Games

背景 在進行 Flutter UI 開發的時候,控制台報出了下麵錯誤: flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════ flut ...


背景

在進行 Flutter UI 開發的時候,控制台報出了下麵錯誤:

flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY >╞═════════════════════════════════════════════════════════
flutter: The following message was thrown during layout:
flutter: A RenderFlex overflowed by 826 pixels on the right.

界面的體現就是黃色區域。

這裡的代碼是在上一篇的基礎上返回下麵的 Widget:

return Row(
      children: <Widget>[
        Image.network(
            'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240')
      ],
    );

模擬器效果如下:

思考

其實一般遇到這種情況,都應該考慮一下是否這樣佈局合理。

上面這個我們只是舉個例子,因為一般如果只有一張圖片,是不需要給他套一層 Row 的。

因為情況比較多,這裡假設有時候真的就需要這麼處理,怎麼辦?

解決方法

如果你某個 Widget 出現了上面的問題,而且真的不是佈局問題,而是真的就是有可能出現這種情況,但是你不希望 debug 模式顯示這個錯誤,那麼可以給他套一層 Expanded。

官網有如下說明:

A widget that expands a child of a RowColumn, or Flex.

Using an Expanded widget makes a child of a RowColumn, or Flex expand to fill the available space in the main axis (e.g., horizontally for a Row or vertically for a Column). If multiple children are expanded, the available space is divided among them according to the flex factor.

所以對於 Row、Column 以及 Flex 都可以用 Expanded 來解決子組件報上面錯誤問題。

所以這裡可以修改為

return Row(
      children: <Widget>[
        Expanded(
          child: Image.network(
              'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'),,
        )
      ],
    );

效果如下:

Expanded 妙用

Expanded 除了可以解決上面的問題之外,還有一個妙用就是比例佈局。

什麼意思呢?

我們寫下代碼,然後給下效果圖你就懂了。

return Column(
      children: <Widget>[
        Expanded(
          flex: 1,
          child: Container(
            color: Colors.red,
          ),
        ),
        Expanded(
          flex: 1,
          child: Container(
            color: Colors.blue,
          ),
        ),
        Expanded(
          flex: 1,
          child: Container(
            color: Colors.grey,
          ),
        ),
      ],
    );

效果圖如下:

可以看出 Expanded 的 flex 屬性會按比例佈局。

Sample

我們來實現一個簡單的 UI。

如下圖,可以看到是一個網路錯誤時,點擊重試的頁面。

假設你之前習慣了 sketch 邊距開發,你看到這個頁面,就直接根據邊距進行開發,寫出了下麵的代碼。

實現方式一:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      home: Scaffold(
        backgroundColor: Color(0xFFF0F1F0),
        body: Center(
          child: _buildWidget(),
        ),
      ),
    );
  }

  Widget _buildWidget() {
    return Container(
      child: Column(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.only(left: 97.0, right: 97.0, top: 125),
            child: Image.asset('assets/images/refresh.png', width: 49, height: 44,),
          ),
          SizedBox(
            height: 42.0,
          ),
          FlatButton(
              padding: const EdgeInsets.symmetric(horizontal: 50.0),
              //註意這裡 alpha 最大值是 255, sketch 上面最大值是 100
              color: Color.fromARGB(255, 13, 46, 172),
              //這裡 onPressed 不能為 null,如果寫 null 會怎樣,大家可以試下~
              onPressed: (){},
              child: Text(
                //演示而已,實際開發需要多語言
                '刷新',
                style: TextStyle(
                    color: Colors.white,
                    fontSize: 12,
                    fontWeight: FontWeight.w600
                ),
              )
          )
        ],
      ),
    );
  }

}

效果如下:

你會發現這種實現方式的適配性會很差,而且可能出現上面的問題。

因此我們看下使用 Expanded 如何實現。

觀察一下,我們發現界面大概可以分成 3 塊。

每一塊占的比例差不多,因此可以如下實現。

實現方式二:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      home: Scaffold(
        backgroundColor: Color(0xFFF0F1F0),
        body: Center(
          child: _buildWidget(),
        ),
      ),
    );
  }

  Widget _buildWidget() {
    return Container(
      child: Column(
        children: <Widget>[
          Expanded(
            flex: 1,
            child: Container(),
          ),
          Image.asset('assets/images/refresh.png', width: 49, height: 44,),
          SizedBox(
            height: 42.0,
          ),
          FlatButton(
              padding: const EdgeInsets.symmetric(horizontal: 50.0),
              //註意這裡 alpha 最大值是 255, sketch 上面最大值是 100
              color: Color.fromARGB(255, 13, 46, 172),
              //這裡 onPressed 不能為 null,如果寫 null 會怎樣,大家可以試下~
              onPressed: (){},
              child: Text(
                //演示而已,實際開發需要多語言
                '刷新',
                style: TextStyle(
                    color: Colors.white,
                    fontSize: 12,
                    fontWeight: FontWeight.w600
                ),
              )
          ),
          Expanded(
            flex: 1,
            child: Container(),
          ),
        ],
      ),
    );
  }

}

效果如下:

其實,看到上面用到的 Column,我們可以直接利用上次說到的一個屬性,就可以很巧妙的實現適配。

實現方式三:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Color(0xFFF0F1F0),
        body: Center(
          child: _buildWidget(),
        ),
      ),
    );
  }

  Widget _buildWidget() {
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Image.asset(
            'assets/images/refresh.png',
            width: 49,
            height: 44,
          ),
          SizedBox(
            height: 42.0,
          ),
          FlatButton(
              padding: const EdgeInsets.symmetric(horizontal: 50.0),
              //註意這裡 alpha 最大值是 255, sketch 上面最大值是 100
              color: Color.fromARGB(255, 13, 46, 172),
              //這裡 onPressed 不能為 null,如果寫 null 會怎樣,大家可以試下~
              onPressed: () {},
              child: Text(
                //演示而已,實際開發需要多語言
                '刷新',
                style: TextStyle(
                    color: Colors.white,
                    fontSize: 12,
                    fontWeight: FontWeight.w600),
              )),
        ],
      ),
    );
  }
}

效果如下:

其中實現方式一隻是說明,實際開發不推薦。

實現方式二和實現方式三都可以,推薦方式三。

相關代碼及 sketch 圖都放到了 GitHub 倉庫

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 持久化存儲是將 Redis 存儲在記憶體中的數據存儲在硬碟中,實現數據的永久保存。我們都知道 Redis 是一個基於記憶體的 nosql 資料庫,記憶體存儲很容易造成數據的丟失,因為當伺服器關機等一些異常情況都會導致存儲在記憶體中的數據丟失。 ...
  • 筆記記錄自林曉斌(丁奇)老師的《MySQL實戰45講》 (本篇內圖片均來自丁奇老師的講解,如有侵權,請聯繫我刪除) 9) --普通索引和唯一索引,應該怎麼選擇? 假如你在維護一個市民系統,每個人都有唯一的身份證號,而且業務代碼也已經保證了不會寫入兩個相同的身份證號。如果需要按身份證號來查找,你可能會 ...
  • Oracle下載與Oracle安裝圖解(Oracle19c,Oracle18c,Oracle12c,Oracle11g) 1、Oracle下載(Oracle11g) oracle下載方法,請根據以下步驟與圖示來下載oracle11g版本: oracle11g下載第1步:打開oracle官方網站 or ...
  • MySQL下載與MySQL安裝圖解(MySQL5.7與MySQL8.0) 1、MySQL下載(MySQL8.0社區版) mysql下載方法,請根據風哥以下步驟與圖示來下載mysql8.0最新社區版本: mysql下載第1步:打開mysql官方網站 mysql下載第2步:downloads mysql ...
  • 例如規定只能在工作時間內更新Student表,可以定義如下觸發器,其中sysdate為系統當前時間 CREATE OR REPLACE TRIGGER secure_student BEFORE INSERT OR UPDATE OR DELETE ON studentBEGIN IF (TO_CH ...
  • 一、HBase表的基本結構 1.概述: 平時常見的MySQL、Oracle資料庫都是傳統型關係資料庫,它們都是按行查詢、按行存儲;而HBase為非關係型資料庫,它是按列存儲的的。 在HBase插入數據時,先輸入數據的格式為rowkey => info => column => value rowke ...
  • 一、準備工作 1、項目build.gradle文件下的dependencies中引入插件: 2、在module的build.gradle文件下頂部依賴插件: 3、在module的build.gradle文件下的dependencies中引入依賴: 二、GreenDao的註解 1、實體@Entity註 ...
  • 一、準備工作在app的build.gradle文件下的dependencies中添加依賴: 二、RxJava的操作符用法: 1、create 2、from 3、just 4、map 5、flatMap 此處用到的getCityWeathData方法返回出來一個泛型為WeathData的Observa ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...