一個Flutter widget自動適配不同UI到Web、Android

上圖

webUI

androidUI

不是dp適配

對的,不是對dp的適配,而是在不同的分變率,改變布局的方式。大的屏幕肯定是要合理利用空間,這樣布局緊湊,不浪費空間,小的屏幕又不能讓大的組件等比壓縮,這樣不光會變丑,還會變的更難觸及,既然Flutter對web的支持,那么肯定要支持不同分辨率,適配不同布局吧,就像我們Android開發,在針對Pad的時候做一個單獨的xml布局來適配一樣。

實現原理

原理很簡單,就是在屏幕寬度到了一定范圍內,然后動態返回不同的Widget,那么拿到屏幕的寬度就是關鍵,其實很簡單

MediaQuery.of(context).size.width

詳細介紹參見官方文檔MediaQuery
大致意思是說,WidgetsAppMaterialApp目前只有它們引入了MediaQuery并隨著它們的變化與當前屏幕指標保持最新,所以這也是為什么當你沒有用這兩個widget布局,最終報錯的原因,用的時候注意。
我們來看個細節哈

WidgetsApp

MaterialApp

WidgetsAppMaterialApp
繼承自StatefulWidget,我們平時寫的組件也大部分都是繼承自StatefulWidget,所以這就說明,你平時自己寫的組件,如果是一個單獨的新頁面,當你用到這個MediaQuery時肯定會報錯,不信你試試哈。
我們知道寬度后就好說了,只需要加入寬度判斷就ok

  static bool isSmallScreen(BuildContext context) {
    return MediaQuery.of(context).size.width < 768;
  }

  static bool isLargeScreen(BuildContext context) {
    return MediaQuery.of(context).size.width > 768;
  }

  static bool isMediumScreen(BuildContext context) {
    return MediaQuery.of(context).size.width > 425 &&
        MediaQuery.of(context).size.width < 1200;
  }

然后在Widget build(BuildContext context)的時候返回不同的布局

 return LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.maxWidth > 768) {
          return largeScreen;
        } else if (constraints.maxWidth < 1200 && constraints.maxWidth > 425) {
          return mediumScreen ?? largeScreen;
        } else {
          return smallScreen ?? largeScreen;
        }
      },
    );

如何使用呢

  ConstrainedBox(
        constraints: BoxConstraints(
            minWidth: constraints.maxWidth, minHeight: constraints.maxHeight),
        child: ResponsiveWidget(
          largeScreen: _buildLargeScreen(context),
          mediumScreen: _buildMediumScreen(context),
          smallScreen: _buildSmallScreen(context),
        ),
      )

ConstrainedBox用于對子組件添加額外的約束,這里就是為了限制布局的寬高都充滿屏幕,準確的說是充滿父容器,保證計算的寬度不會出現失誤。

官方動態適配方案

官方解讀:
responsive響應式應用程序會根據屏幕或窗口的大小和形狀來布局其UI。當同一個應用程序可以在各種設備(從手表,手機,平板電腦到筆記本電腦或臺式機)上運行時,這尤其必要。當用戶在筆記本電腦或臺式機上調整窗口大小或更改手機或平板電腦的方向時,應用程序應通過相應地重新排列UI來做出響應。
官方推薦博客:

國外開源方案

image.png

responsive_builder這個框架的原理跟我介紹的一樣,封裝的會詳細一些。請參考。

我介紹的方案地址

responsive_widget.dart

在線看效果

ibaozi.cn

結束

以后碰到Flutter中實用的東東,在分享給你們哈。歡迎留言討論。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 國慶后面兩天在家學習整理了一波flutter,基本把能擼過能看到的代碼都過了一遍,此文篇幅較長,建議保存(star...
    Nealyang閱讀 4,369評論 1 17
  • Flutter是開源并且免費的,擁有現代的響應式框架特性,高速的2D渲染引擎,方便快捷的開發工具以及各種開箱即用的...
    luehning閱讀 580評論 0 0
  • 1、 Widget 基本概念 1、flutter中一切皆是Widget,不只是構建頁面的UI,還有如布局類、事件處...
    風之化身呀閱讀 1,489評論 0 0
  • 時光都一天天過去,新的明天又將迎來,就這樣迎了小喬。 ...
    皇帝的簡稱閱讀 378評論 1 0
  • 這個操作符可以用來快速的對 nil 進行判斷,當左側的值是 非 nil時返回其value左側的值,為nil時返回其...
    GavinKang閱讀 1,849評論 1 0