FragmentContainerView、ViewPager、ViewPager2與 BottomNaviagtionView結合使用的區別

来源:https://www.cnblogs.com/yilechen/p/18429824
-Advertisement-
Play Games

現在市面的應用界面大多是通過一個Fragment容器+底部導航欄框架來實現頁面切換的,而當我們想要去搭建一個這樣的框架時,上層的Fragment容器是可選的,常見的有FragmentContanerView、ViewPager、ViewPager2。我們應該如何選擇呢?這時就需要考慮這三者的自身自帶 ...



現在市面的應用界面大多是通過一個Fragment容器+底部導航欄框架來實現頁面切換的,而當我們想要去搭建一個這樣的框架時,上層的Fragment容器是可選的,常見的有FragmentContanerView、ViewPager、ViewPager2。我們應該如何選擇呢?這時就需要考慮這三者的自身自帶的一些特性區別:

在我目前寫的項目中這三者都有使用到,一開始並沒有覺得有什麼區別,因為寫的都是一些很簡單的項目。但在一次使用FragmentContainerView的過程中,我明顯的感覺到了其與ViewPager2的一個顯著區別:切換Fragment時生命周期方法的調用。

在這個使用FragmentContainerView+BottomNavigationView的項目中,我在其中一個頁面加入了自定義的自動輪播圖控制項,而當我通過底部導航欄切換到另一界面再切回來時,我發現我的輪播圖控制項總是會自動從第一張圖開始載入,而在我之前使用ViewPager2+BottomNaviagtionView的項目中我也使用了自動輪播圖控制項,但是並沒有出現這個問題:即通過底部導航欄切換到另一個頁面再切回來並不會使輪播圖控制項重新輪播。

我開始思考:是什麼導致了自動輪播圖控制項每次切回來都會從頭開始輪播?

以下是我的排查過程:

一開始,我懷疑我的輪播圖自動輪播的邏輯寫的有問題,返回查看,發現與另一個項目的是一樣的,那就可以排除這個原因

進而,我開始思考輪播圖的載入時機。我的輪播圖數據是網路數據,而請求輪播圖網路數據是在Fragment的onViewCreated()生命周期方法中執行的。也就是說與Fragment的生命周期方法調用時機有關。

1.FragmentContainerView+BottomNavigationView切換Fragment時的生命周期調用情況:

我開始在Fragment的各個生命周期方法中打Log,然後發現,當我通過底部導航欄切換FragmentContainerView中的fragment時,被切換的Fragment除了首頁的Fragment只會立即執行onPause()->onStop()->onDestroyView(),其他的都會立即執行onPause()->onStop()->onDestroyView(onDestory(),當我再切換回來之後,會執行onCreatedView()->onViewCreated()。也就是說每當我切換回去之後輪播圖都會再重新請求一次數據,從而導致了每次切換回輪播圖界面輪播圖都會重新開始輪播。

首頁Fragment被切換後的生命周期調用情況

重新切迴首頁Fragment後的生命周期調用情況

其他Fragment被切換後的生命周期調用情況

重新切回其他Fragment後的生命周期調用情況

2.ViewPager2+BottomNavigationView切換Fragment的生命周期調用情況:

而後,我又返回去查看另一個項目(即使用ViewPager2+BottomNavigationView的)的界面切換導致的Fragment生命周期方法的變化。發現:當通過BottomNavigationView切換fragment時,被切換的fragment只會執行onPause(),但並不會立即執行onStop(),而是等待一段時間後或當用戶退出應用才會調用onStop()方法;且當切回去時,也不會重新執行onCreatedView()->onViewCreated(),onCreatedView()->onViewCreated()只有當Fragment首次被展示時才會調用。故使用ViewPager2的項目中切換Fragment不會導致輪播圖數據重新載入而導致輪播圖重新輪播。

Fragment被切換後生命周期調用情況

Fragment被切回來後生命周期調用情況

3.ViewPager+BottomNaviagtionView切換Fragment的生命周期調用情況:

​ 而後,我又研究了一下ViewPager+BottomNaviagtionView切換fragment的生命周期調用情況。ViewPager有預載入功能,比較複雜一點

​ 同樣是只有三個頁面(Title,Leaderboard,Register),由BottomNavigationView控制切換:

​ 初次載入時,ViewPager會預載入其臨近的一個Fragment,在這個例子中,就是顯示首頁Title頁面時也預載入了Leaderboard頁面,生命周期調用如下:


當我從Title切換到臨近的Leaderboard頁面時,被切換的Title頁面的生命周期沒有任何變化,切換後的Leaderboard頁面也沒有任何變化(因為其已經被預載入過了),而此時,與Leaderboard臨近的Register頁面也會被預載入,生命周期調用如下:

而當我從Leaderboard頁面切換到第三個頁面Register時,Leaderboard頁面和Register頁面的生命周期都不會發生變化,但第一個頁面Title會被銷毀,生命周期調用如下:

同樣的,當我從第三個頁面Register切換到第二個頁面Leaderboard時,第一個頁面Title又會被重新載入,生命周期調用如下:

當我再從第二個頁面Leaderboard切換到第一個界面時,第三個頁面Register又會被銷毀,生命周期方法調用如下:

由上述測試我們可以看到ViewPager的預載入機制和頁面銷毀機制,且當界面上只有三個頁面時,除非用戶退出界面,否則第二個頁面是永遠不會銷毀的。

4.總結:

(1)FragmentContainerView+BottomNavigationView:

既沒有預載入機制也沒有緩存機制,每切換一次,被切換的Fragment就會被銷毀,下次切回來要重新創建View:onCreatedView()->onViewCreated()

(2)ViewPager2+BottomNavigationView:

預設是沒有預載入機制的,除非我們手動調用viewPager.offscreenPageLimit 屬性進行設置,否則預設是沒有預載入(其預載入與ViewPager的預載入機制還不太一樣,預載入的界面不會調用onResume()渲染界面,而ViewPager的預載入界面是直接渲染好的),但是預設有緩存機制,當頁面被載入到界面上後不會銷毀(除非用戶退出界面),只會暫停onPause,再次回來時直接onResume()

(3)ViewPager+BottomNavigationView:

預設有預載入機制,會預載入臨近的左右頁面。也有預設的緩存機制,但與ViewPager2的不同,當從本頁面切換到間隔一個的頁面,本頁面就會被銷毀(如從1切換到3時,1就會被銷毀)。


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

-Advertisement-
Play Games
更多相關文章
  • Apache SeaTunnel 2.3.8版本即將於大家見面,近日,Apache SeaTunnel PMC Member 範佳在社區的交流會上為大家提前透露了關於這個新版本即將進行的功能與特性更新概況,詳細內容如下: SeaTunnel 簡介 SeaTunnel是一個高性能的開源分散式數據集成系 ...
  • 在大數據時代,工作流任務調度系統成為了數據處理和業務流程管理的核心組件,在大數據平臺的構建和開發過程中尤為重要。隨著數據量的激增和業務需求的多樣化,合理的任務調度不僅能夠提高資源利用率,還能保證業務流程的穩定和高效運行。本文將結合實際場景,探討目前市面上常見的工作流任務調度及其關鍵特性。 一、工作流 ...
  • 本文轉自YashanDB官網,具體內容請見https://www.yashandb.com/newsinfo/7441388.html?templateId=1718516 問題現象 客戶剛開始使用YashanDB odbc的時候,需要查看調用日誌詳情, 確認相應介面調用情況。 問題的風險及影響 客 ...
  • postgresql 與PostGis 離線環境安裝 上傳文件至伺服器 #安裝所需依賴 yum install /opt/PGsql-13-gis/rpm/* -y Postgresql安裝 tar -zxvf postgresql-13.2.tar.gz #進入該目錄 ./configure -- ...
  • 1. 讓數據可信 1.1. 每個終端用戶(End User)都有一個共同的需求:訪問想要的數據 1.2. 真的能夠相信我正在訪問的這些數據嗎? 1.2.1. 終端用戶很快就會發現,訪問數據和相信正在訪問的數據是兩回事 1.2.2. 訪問數據和相信數據不是同一回事 1.2.3. 如果數據不可信,可能會 ...
  • Sql介紹 與 Sql基礎查詢 SQL SQL也稱為結構化查詢語言(Structure Query Language),是一種用於管理和操作關係型資料庫的標準化電腦語言,SQL語言廣泛應用於各種關係型資料庫系統(RDBMS)如Mysql,Oracle,Microsoft SQL Server等等 ...
  • 什麼是骨架屏 在客戶端開發中,我們總是需要等待拿到服務端的響應後,再將內容呈現到頁面上,那麼在用戶發起請求到客戶端成功拿到響應的這段時間內,應該在屏幕上呈現點什麼好呢? 答案是:骨架屏 那麼什麼是骨架屏呢,來問下 GPT: 骨架屏(Skeleton Screen)是一種現代的用戶界面設計技術,用於提 ...
  • 大家好,我是 V 哥,今天給大家分享10款好用的 HarmonyOS的工具庫,在開發鴻蒙應用時可以用下,好用的工具可以簡化代碼,讓你寫出優雅的應用來。廢話不多說,馬上開整。 1. efTool efTool是一個功能豐富且易用的相容API12的HarmonyOS工具庫,通過諸多實用工具類的使用,旨在 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...