Flutter螢幕適配 - 等比縮放

小白cz發表於2021-05-12

Flutter螢幕適配

Github專案地址:VPixel

移動端UI適配無非就2種型別

  • 多UI動態響應
  • 單UI等比縮放

這裡來聊聊比較常見的 單UI等比縮放 (畢竟省事,手動狗頭~~~)

在Flutter裡,預設畫素單位是dp,由於移動裝置 尺寸 & 解析度 的不一致,導致不同裝置有視覺差異,這問題可以通過按設計圖絕對寬度基準,進行等比縮放,那麼如何實現呢?

適配過程

由於Web,Desktop(PS:都可以手動調整介面尺寸)的正式版釋出,使得UI的尺寸變得更多元化

處理流程

  1. 響應UI尺寸的變化

通過註冊監聽器,可得知UI尺寸的變更

//UI尺寸發生變化時,會回撥 WidgetsBindingObserver 的 didChangeMetrics 函式
WidgetsBinding.instance.addObserver(WidgetsBindingObserver observer);
複製程式碼
  1. 更改縮放比

由 didChangeMetrics 函式得知UI尺寸變更,這裡作出變更縮放比處理

//獲取最新UI尺寸資料
final data = MediaQueryData.fromWindow(WidgetsBinding.instance?.window);
//縮放比 = data.size.width / 設計圖尺寸;
複製程式碼
  1. 通知UI重建

最後通過setState函式進行通知重新整理

實現方式可看專案原始碼,或者後期分解~~~

使用方式

  1. 匯入專案
dependencies:
  # 虛擬畫素
  vpixel:
    git:
      url: https://github.com/XiaoBaiCZ/vPixel.git
      ref: stable
複製程式碼
  1. 使用VPixel包住需要縮放的Widget,推薦 入口Widget(全域性通用)
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //入口設定VPixel
    return VPixel(
      //設計稿寬度尺寸
      designWidth: 750,
      builder: (ctx) {
        //原入口Widget
        //App範圍內都能使用vpx,如Body
        return MaterialApp(
          home: Scaffold(
            body: Body(),
          ),
        );
      },
    );
  }
}

//App範圍內可用vpx填寫設計稿尺寸
class Body extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      alignment: Alignment.center,
      children: [
        //3等分方塊
        //App範圍內可用vpx填寫設計稿尺寸
        Positioned(
          top: 0,
          left: 0,
          child: Container(color: Colors.red, width: 250.vpx, height: 250.vpx,),
        ),
        Positioned(
          top: 0,
          child: Container(color: Colors.green, width: 250.vpx, height: 250.vpx,),
        ),
        Positioned(
          top: 0,
          right: 0,
          child: Container(color: Colors.blue, width: 250.vpx, height: 250.vpx,),
        ),
        //2等分方塊
        Positioned(
          bottom: 0,
          left: 0,
          child: Container(color: Colors.yellow, width: 375.vpx, height: 375.vpx,),
        ),
        Positioned(
          bottom: 0,
          right: 0,
          child: Container(color: Colors.orange, width: 375.vpx, height: 375.vpx,),
        ),
      ],
    );
  }
}
複製程式碼
  1. 效果圖

5EBB03B8-D00D-436A-8155-73303A6334FC.png

6A8CD3B3-6FDD-4BB7-AFB6-E7FA14BBEBDF.png

相關文章