整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          (十三) Flutter入門學習 之 屏幕適配

          (十三) Flutter入門學習 之 屏幕適配

          前移動端的設備已經非常多,并且不同的設備手機屏幕也不相同。

          目前做移動端開發都要針對不同的設備進行一定的適配,無論是移動原生開發、小程序、H5頁面。

          Flutter中如何針對不同的手機屏幕來進行適配呢?我們一起來聊聊這個話題。

          一. Flutter單位

          1.1. Flutter中的單位

          在進行Flutter開發時,我們通常不需要傳入尺寸的單位,那么Flutter使用的是什么單位呢?

          • Flutter使用的是類似于iOS中的點pt,也就是point。
          • 所以我們經常說iPhone6的尺寸是375x667,但是它的分辨率其實是750x1334。
          • 因為iPhone6的dpr(devicePixelRatio)是2.0,iPhone6plus的dpr是3.0

          iPhone設備參數

          在Flutter開發中,我們使用的是對應的邏輯分辨率

          1.2. Flutter設備信息

          獲取屏幕上的一些信息,可以通過MediaQuery:

          // 1.媒體查詢信息
          final mediaQueryData=MediaQuery.of(context);
          
          // 2.獲取寬度和高度
          final screenWidth=mediaQueryData.size.width;
          final screenHeight=mediaQueryData.size.height;
          final physicalWidth=window.physicalSize.width;
          final physicalHeight=window.physicalSize.height;
          final dpr=window.devicePixelRatio;
          print("屏幕width:$screenWidth height:$screenHeight");
          print("分辨率: $physicalWidth - $physicalHeight");
          print("dpr: $dpr");
          
          // 3.狀態欄的高度
          // 有劉海的屏幕:44 沒有劉海的屏幕為20
          final statusBarHeight=mediaQueryData.padding.top;
          // 有劉海的屏幕:34 沒有劉海的屏幕0
          final bottomHeight=mediaQueryData.padding.bottom;
          print("狀態欄height: $statusBarHeight 底部高度:$bottomHeight");

          獲取一些設備相關的信息,可以使用官方提供的一個庫:

          dependencies:
            device_info: ^0.4.2+1


          二. 適配方案

          2.1. 適配概述

          假如我們有下面這樣一段代碼:

          • 在屏幕中間顯示一個200*200的Container
          • Container中有一段文字是30
          class HYHomePage extends StatelessWidget {
            @override
            Widget build(BuildContext context) {
              return Scaffold(
                appBar: AppBar(
                  title: Text("首頁"),
                ),
                body: Center(
                  child: Container(
                    width: 200,
                    height: 200,
                    color: Colors.red,
                    alignment: Alignment.center,
                    child: Text("Hello World", style: TextStyle(fontSize: 30, color: Colors.white),),
                  ),
                ),
              );
            }
          }

          上面的代碼在不同屏幕上會有不同的表現:

          • 很明顯,如果按照上面的規則,在iPhone5上面,尺寸過大,在iPhone6plus上面尺寸過小
          • 在開發中,我們應該可以根據不同的屏幕來完成尺寸的縮放

          不同屏幕表現


          在前端開發中,針對不同的屏幕常見的適配方案有下面幾種:

          • rem:
            • rem是給根標簽(HTML標簽)設置一個字體大小;
            • 但是不同的屏幕要動畫設置不同的字體大小(可以通過媒體查詢,也可以通過js動態計算);
            • 其它所有的單位都使用rem單位(相對于根標簽);
          • vw、wh:
            • vw和vh是將屏幕(視口)分成100等份,一個1vw相當于是1%的大小;
            • 其它所有的單位都使用vw或wh單位;
          • rpx:
            • rpx是小程序中的適配方案,它將750px作為設計稿,1rpx=屏幕寬度/750;
            • 其它所有的單位都使用rpx單位;

          這里我采用小程序的rpx來完成Flutter的適配

          2.2. rpx適配

          小程序中rpx的原理是什么呢?

          • 不管是什么屏幕,統一分成750份
          • 在iPhone5上:1rpx=320/750=0.4266 ≈ 0.42px
          • 在iPhone6上:1rpx=375/750=0.5px
          • 在iPhone6plus上:1rpx=414/750=0.552px

          rpx的對應關系


          那么我們就可以通過上面的計算方式,算出一個rpx,再將自己的size和rpx單位相乘即可:

          • 比如100px的寬度:100 * 2 * rpx
          • 在iPhone5上計算出的結果是84px
          • 在iPhone6上計算出的結果是100px
          • 在iPhone6plus上計算出的結果是110.4px

          我們自己來封裝一個工具類:

          • 工具類需要進行初始化,傳入context
            • 可以通過傳入context,利用媒體查詢獲取屏幕的寬度和高度
            • 也可以傳入一個可選的參數,以什么尺寸作為設計稿
          class HYSizeFit {
            static MediaQueryData _mediaQueryData;
            static double screenWidth;
            static double screenHeight;
            static double rpx;
            static double px;
          
            static void initialize(BuildContext context, {double standardWidth=750}) {
              _mediaQueryData=MediaQuery.of(context);
              screenWidth=_mediaQueryData.size.width;
              screenHeight=_mediaQueryData.size.height;
              rpx=screenWidth / standardWidth;
              px=screenWidth / standardWidth * 2;
            }
            
            // 按照像素來設置
            static double setPx(double size) {
              return HYSizeFit.rpx * size * 2;
            }
            
            // 按照rxp來設置
            static double setRpx(double size) {
              return HYSizeFit.rpx * size;
            }
          }

          初始化HYSizeFit類的屬性:

          • 注意:必須在已經有MaterialApp的Widget中使用context,否則是無效的
          class HYHomePage extends StatelessWidget {
            @override
            Widget build(BuildContext context) {
              // 初始化HYSizeFit
              HYSizeFit.initialize(context);
              return null;
            }
          }

          使用rpx來完成屏幕適配:

          class HYHomePage extends StatelessWidget {
            @override
            Widget build(BuildContext context) {
              HYSizeFit.initialize(context);
              return Scaffold(
                appBar: AppBar(
                  title: Text("首頁"),
                ),
                body: Center(
                  child: Container(
                    width: HYSizeFit.setPx(200),
                    height: HYSizeFit.setRpx(400),
                    color: Colors.red,
                    alignment: Alignment.center,
                    child: Text("Hello World", style: TextStyle(fontSize: HYSizeFit.setPx(30), color: Colors.white),),
                  ),
                ),
              );
            }
          }

          我們來看一下實現效果:

          rpx適配方案


          屏幕適配也可以使用第三方庫:flutter_screenutil

          • https://github.com/OpenFlutter/flutter_screenutil

          原文出處:https://mp.weixin.qq.com/s/z21YZ4FhSswpDWn4KpK6jw(侵權刪除)

          著網絡與科技的快熟發展,越來越多的手機廠商開始打起手機之間的戰爭,手機的快速發展也使得越來越多的人開始使用手機上網。移動設備正超過桌面設備,成為訪問互聯網的最常見終端。那么就會出現一個問題,如何才能讓PC端的網頁在手機上正常顯示?手機與PC的屏幕寬度有著很大的區別,會造成同樣的內容在手機與PC端出現兩種不同的顯示結果。那該如何才能使得手機與PC都能對網頁呈現出令人滿意的結果呢,本文收集了以下幾種方法,有興趣的小伙伴們可以看下:

          1、在網頁代碼的頭部,加入一行viewport元標簽。

          viewport是網頁默認的寬度和高度,上面這行代碼的意思是,網頁寬度默認等于屏幕寬度(width=device-width),原始縮放比例(initial-scale=1)為1.0,即網頁初始大小占屏幕面積的100%。

          注意:該方式不支持IE8及IE8以下的版本

          2、不使用絕對寬度

          由于網頁會根據屏幕寬度調整布局,所以不能使用絕對寬度的布局,也不能使用具有絕對寬度的元素。對圖像來說也是這樣。

          具體說,CSS代碼不能指定像素寬度:width:xxx px;

          只能指定百分比寬度: width: xx%; 或者 width:auto;

          3、使用相對大小的字體

          字體也不能使用絕對大小(px),只能使用相對大小(em或者rem)

          例如: body

          上面的代碼指定,字體大小是頁面默認大小的100%,即16像素(1em=16px)。

          h1

          h1的大小是默認大小的1.5倍,即24像素(24/16=1.5)

          將想要的像素去除默認的16像素可以得到em

          4、流動布局(fluid grid)

          "流動布局"的含義是,各個區塊的位置都是浮動的,不是固定不變的。

          .main

          .leftBar

          float的好處是,如果寬度太小,放不下兩個元素,后面的元素會自動滾動到前面元素的下方,不會在水平方向overflow(溢出),避免了水平滾動條的出現。

          5、媒體查詢器@media

          "自適應網頁設計"的核心,就是CSS3引入的MediaQuery模塊。

          它的意思就是,自動探測屏幕寬度,然后加載相應的CSS文件。

          上面的代碼意思是,如果屏幕寬度小于400像素(max-device-width: 400px),就加載tinyScreen.css文件。

          如果屏幕寬度在400像素到600像素之間,則加載smallScreen.css文件。

          輯導語:雖然國內軟件的iPad用戶占比不大,但依然存在著橫屏適配的需求。本文作者講述了自己做iPad橫屏適配的背景,并對競品的適配方式進行了分析研究,用自己的親身經歷提供了參考,推薦對ipad橫屏適配感興趣的童鞋閱讀。

          一、背景

          在我參與的一款資料查詢 App 中,對 iPad 只支持豎屏以手機 UI 尺寸拉伸,每個季度都有用戶反饋希望適配 iPad 橫屏。經過詢問用戶發現,因為 iPad mini 尺寸剛好可以放在工作服口袋中,隨時拿出來使用,而 iPad 屏幕遠比手機大,瀏覽資料視野更大更舒服。

          但另外一方面,后臺數據顯示當前 iPad 用戶占比只有 1%,用戶呼聲夠不上星星之火,不足以燎原。先別談說服團隊做 iPad 橫屏適配,連說服自己都難。本來以為這事就像水中投石,水波消散就沒有下文了。直到有一天,同樣是資深用戶的高管自己拿著 iPad 裝上我們的 App 用了幾天,終于忍不了,開始推動 iPad 橫屏適配。

          二、參考

          我們肯定不是第一個做 iPad 橫屏適配的,但在網上搜了一圈,別說橫屏適配,連 iPad 界面設計的文章都很少,下面 3 篇算不錯的。這也是我決定寫下本文的原因,為后來者提供經驗,少踩坑。

          1. 《利用好 iPad 的大屏幕 —— 如何為 iPadOS 14 設計 app?》,https://steppark.net/15942969497015.html
          2. 《iPad 交互設計探索系列:iPad 適用產品篇》,https://www.jianshu.com/p/65211fddefb9
          3. 《iPad 交互設計探索系列:iPad 導航設計篇》,https://www.jianshu.com/p/0c8e315d39d4

          三、研究

          沒得經驗參考就只能先從競品分析開始了。經過對 iOS 系統應用、微信、QQ、微信閱讀、得到、豆瓣、淘寶和有道詞典的分析,我和同事總結成 5 種橫屏適配模式。

          1. 內容響應式

          典型 App:iOS 應用商店

          特征:標題欄和 Tabbar 通欄拉伸,內容區根據寬度向右響應式布局。

          適用場景:全部場景。

          評價:靈活性和用戶體驗都很好,但設計和開發成本很大。

          2. 左右分欄

          典型 App:iOS 設置、淘寶、微信、QQ

          特征:左右分開顯示,左邊通常固定顯示首頁或者目錄導航。右側根據左側選擇顯示對應的詳情內容。

          適用場景:頻繁需要使用導航切換內容。

          評價:用戶體驗適中,合理的利用橫屏更大地展示更多的內容。設計成本小,需額外設計一個右側默認為空的情況。開發成本要看是否改程序架構,相當于把手機兩個手機界面合并成一個屏幕,可能有些程序架構很難這么修改。

          3. 按豎屏寬度顯示

          典型 App:微信閱讀

          特征:標題欄和 Tabbar 通欄拉伸,內容直接按豎屏的寬度顯示。

          適用場景:全部場景。

          評價:用戶體驗適中,設計與開發成本小,大多數產品采用此模式,但是沒有更好的展現橫屏寬屏的優勢。

          4. 全屏通欄拉伸

          典型 App:豆瓣

          特征:橫屏為全屏通欄拉伸,所有元素與豎屏一致。

          適用場景:全部場景。

          評價:設計和開發成本最小,但是相當于沒有適配。用戶體驗較差,橫屏情況下內容集中,左側右側很空,或者被拉得很長,閱讀體驗較差。

          5. 混合模式

          當然也不是所有 App 都采用單一的模式。比如微信閱讀,在其他頁面是按豎屏寬度顯示。但到了圖書閱讀界面,則是左右分欄充分利用 iPad 大屏幕展現內容。

          以上競品分析所有截圖我們都保存在 Figma 中,有需要的讀者可前往獲取。

          鏈接:https://www.figma.com/community/file/1071850659054902697/iPad-橫屏適配競品分析

          四、執行

          非常遺憾的是雖然高管牽頭做適配,但開發資源確實有限。不能為了設計師邀功拿業績就從頭把 iOS App 重構一遍,因此我們決定用最少的資源做最核心的優化。

          適配計劃分為 2 期。第 1 期將所有頁面用按豎屏寬度顯示進行橫屏適配。第 2 期挑選核心頁面用內容響應式或左右分欄進行優化。

          1. 先開發再驗收

          在第 1 期我們就踩坑了,按照原來的工作流程,我們將所有的 iPad 橫屏頁面做好線框圖、再輸出所有視覺效果圖。雖然都是線上頁面不用重新設計,只需要拉伸畫面或者調整間距,但所有線上頁面也是一個不小的工作量。

          就在進行過程中,iOS 工程師就皺著眉頭來提議,由于代碼架構和資源所限,設計師如果調整的視覺效果圖未必能 100% 實現。不如反過來,讓他先把所有頁面強行橫屏,再由設計師走查發現問題進行修改,這樣節省時間效果也可控。

          可見,不同的項目類型可以采取不同的工作流程。iPad 橫屏適配項目流程和常規工作流程剛好相反,以往是先設計再開發,改成先開發再走查,節省設計師產出效果圖時間,也保障最終實現效果。

          2. 核心場景決定核心頁面

          在第 2 期挑選核心頁面時,我也犯了錯誤。最開始我覺得核心是臉面,因此挑選 Tabbar 導航的首頁、個人中心等用戶一打開 App 就看得到的頁面進行優化。但實際上用戶真正的核心使用場景是在詳情頁查閱資料,這才是真正的核心頁面。

          在得到主管糾正后,我們轉而開始為資料閱讀頁面提供左內容右目錄的布局,便于用戶方便地在長文中精確定位想讀的內容。

          2 期計劃并非適配的終結,隨著 App 功能的迭代,此后老界面修改和新界面設計需要考慮到 iPad 橫屏的適配問題,就成為了日常工作的內容了。

          五、總結

          按照以往的項目總結,最后應該匯報項目數據結果。但由于 iPad 用戶本身可憐的占比,即使我們官方公眾號推文宣布適配 iPad 橫屏后,也沒有 iPad 用戶站出來點贊,而是又引發出使用華為、小米等安卓 Pad 的用戶,要求也適配。

          考慮到不同的安卓品牌適配方式不一樣,而且安卓廠商自己又有平行世界等通用兼容方案,我們就沒再繼續參與了。

          雖然沒有外部用戶反饋,但公司內部同事和開發團隊使用后確實感覺很棒。所以我覺得這次適配項目真正值得思考的是:如果一個需求用戶反饋很少,也沒有數據支撐,但對體驗影響很大,如何推動團隊進行優化呢?

          作者:龍爪槐守望者,微信公眾號:龍爪槐守望者

          本文由 @龍爪槐守望者 原創發布于人人都是產品經理。未經許可,禁止轉載。

          題圖來自 Unsplash,基于 CC0 協議


          主站蜘蛛池模板: 尤物精品视频一区二区三区 | 精品国产一区二区三区不卡| 亚洲av乱码一区二区三区香蕉| 国产丝袜视频一区二区三区| 亚洲综合无码精品一区二区三区| 一区二区在线播放视频| 日韩一区二区三区不卡视频 | 亚洲熟女乱综合一区二区| www一区二区三区| 国产激情з∠视频一区二区| 性色AV一区二区三区| 无码一区二区三区亚洲人妻| 国产亚洲一区二区三区在线观看 | 午夜视频久久久久一区| 精品亚洲一区二区三区在线观看 | 国产福利电影一区二区三区久久老子无码午夜伦不 | 亚洲日本一区二区| 久久精品免费一区二区喷潮| 亚洲国产精品一区二区第四页 | 亚洲不卡av不卡一区二区| 人妻夜夜爽天天爽一区| 亚洲日本精品一区二区| 亚洲国模精品一区| 在线观看国产一区二区三区 | 国产一区二区内射最近更新| 精品视频午夜一区二区| 亚无码乱人伦一区二区| 亚洲一区二区三区无码影院| 日韩视频在线一区| 无码一区二区三区免费视频| 无码中文字幕一区二区三区| 一区二区三区日韩精品| 国产精品毛片VA一区二区三区| chinese国产一区二区| 精品成人一区二区三区四区| 精品一区二区三区水蜜桃| 风流老熟女一区二区三区| 国产一区二区三区免费视频| 国产SUV精品一区二区88| 好吊妞视频一区二区| 狠狠爱无码一区二区三区|