Activity動態切換Fragment

Activity 動態切換 Fragment 是 Android 開發中常見的需求,用于構建靈活的用戶界面。 以下是實現 Activity 動態切換 Fragment 的幾種方法,以及一些最佳實踐:

1. 使用 FragmentManagerFragmentTransaction (推薦)

這是最常用和推薦的方法。 FragmentManager 管理 Activity 中的 Fragment,FragmentTransaction 用于執行 Fragment 的添加、替換、移除等操作。

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;public class MainActivity extends AppCompatActivity {private FragmentManager fragmentManager;private Fragment currentFragment;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 獲取 FragmentManagerfragmentManager = getSupportFragmentManager();// 初始化第一個 Fragmentif (savedInstanceState == null) { // 避免 Activity 重建時重復添加replaceFragment(new FragmentA(), false);}// 設置按鈕點擊事件Button buttonA = findViewById(R.id.button_a);Button buttonB = findViewById(R.id.button_b);buttonA.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {replaceFragment(new FragmentA(), true);}});buttonB.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {replaceFragment(new FragmentB(), true);}});}// 替換 Fragment 的方法public void replaceFragment(Fragment fragment, boolean addToBackStack) {// 創建 FragmentTransactionFragmentTransaction transaction = fragmentManager.beginTransaction();// 設置動畫 (可選)// transaction.setCustomAnimations(R.anim.slide_in, R.anim.slide_out);// 替換 Fragmenttransaction.replace(R.id.fragment_container, fragment);// 可選:添加到 BackStack,允許用戶按返回鍵返回上一個 Fragmentif (addToBackStack) {transaction.addToBackStack(null); // 可以指定 BackStack 的名稱}// 提交事務transaction.commit();// 記錄當前 FragmentcurrentFragment = fragment;}
}

解釋:

  • R.id.fragment_container: 這是 Activity 布局文件中用于放置 Fragment 的?FrameLayout?或其他容器的 ID。
  • getSupportFragmentManager(): 獲取?FragmentManager?的實例。 對于使用 AndroidX 的項目,使用?getSupportFragmentManager()。 對于舊項目,使用?getFragmentManager()
  • beginTransaction(): 創建一個?FragmentTransaction?對象,用于執行 Fragment 操作。
  • replace(containerViewId, fragment): 將指定容器中的現有 Fragment 替換為新的 Fragment。
  • addToBackStack(String name): 將 FragmentTransaction 添加到 BackStack。 當用戶按下返回鍵時,會從 BackStack 中彈出最后一個 FragmentTransaction,并恢復到之前的狀態。?name?參數是 BackStack 的名稱,可以用于以后查找和管理 BackStack。 如果不需要 BackStack,可以省略此行。
  • commit(): 提交 FragmentTransaction,執行 Fragment 的替換操作。?重要:?commit()?是異步的。
  • commitNow(): 立即執行 FragmentTransaction。 通常不推薦使用,因為它會阻塞主線程。
  • currentFragment: 保存當前顯示的 Fragment 的引用,方便以后操作。
  • savedInstanceState == null: 在?onCreate()?方法中檢查?savedInstanceState?是否為?null,以避免在 Activity 重建時重復添加 Fragment。

2. 使用 add()hide()/show() (適用于多個 Fragment 并存的情況)

如果需要在 Activity 中同時顯示多個 Fragment,可以使用 add() 方法將 Fragment 添加到容器中,然后使用 hide()show() 方法來控制 Fragment 的可見性。

public class MainActivity extends AppCompatActivity {private FragmentManager fragmentManager;private FragmentA fragmentA;private FragmentB fragmentB;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);fragmentManager = getSupportFragmentManager();// 初始化 FragmentfragmentA = new FragmentA();fragmentB = new FragmentB();// 添加 FragmentFragmentTransaction transaction = fragmentManager.beginTransaction();transaction.add(R.id.fragment_container, fragmentA, "fragmentA");transaction.add(R.id.fragment_container, fragmentB, "fragmentB");transaction.hide(fragmentB); // 默認隱藏 FragmentBtransaction.commit();// 設置按鈕點擊事件Button buttonA = findViewById(R.id.button_a);Button buttonB = findViewById(R.id.button_b);buttonA.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {showFragmentA();}});buttonB.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {showFragmentB();}});}private void showFragmentA() {FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.hide(fragmentB);transaction.show(fragmentA);transaction.commit();}private void showFragmentB() {FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.hide(fragmentA);transaction.show(fragmentB);transaction.commit();}
}

解釋:

  • add(containerViewId, fragment, tag): 將 Fragment 添加到容器中,并為其指定一個標簽。 標簽可以用于以后查找 Fragment。
  • hide(fragment): 隱藏指定的 Fragment。
  • show(fragment): 顯示指定的 Fragment。
  • findFragmentByTag(tag): 根據標簽查找 Fragment。

3. 使用 ViewPager (適用于滑動切換 Fragment 的情況)

如果需要在 Activity 中實現滑動切換 Fragment 的效果,可以使用 ViewPagerFragmentPagerAdapterFragmentStatePagerAdapter

  • FragmentPagerAdapter: 適用于 Fragment 數量較少且固定的情況。 它會將所有 Fragment 保存在內存中。
  • FragmentStatePagerAdapter: 適用于 Fragment 數量較多或動態變化的情況。 它只會將當前顯示的 Fragment 保存在內存中,其他 Fragment 會被銷毀。

4. 使用 Navigation Component (適用于復雜的導航結構)

如果應用具有復雜的導航結構,可以考慮使用 Android Jetpack 的 Navigation Component。 Navigation Component 提供了一個聲明式的導航系統,可以簡化 Fragment 的切換和管理。

最佳實踐:

  • 使用?replace()?方法進行 Fragment 替換,而不是?add()?和?remove()?replace()?方法更簡潔,并且可以避免一些潛在的問題。
  • 使用?addToBackStack()?方法將 FragmentTransaction 添加到 BackStack,以便用戶可以通過按返回鍵返回上一個 Fragment。
  • 在?onCreate()?方法中檢查?savedInstanceState?是否為?null,以避免在 Activity 重建時重復添加 Fragment。
  • 使用 Fragment 的標簽 (tag) 來查找 Fragment。
  • 避免在 Fragment 的?onCreateView()?方法中執行耗時的操作,否則可能會導致 UI 卡頓。
  • 使用?commitAllowingStateLoss()?方法來提交 FragmentTransaction,以避免?IllegalStateException?但是,請注意,commitAllowingStateLoss()?可能會導致一些數據丟失。
  • 使用 ViewModel 來管理 Fragment 的數據,以便在 Activity 重建時保留數據。
  • 使用 LiveData 來觀察 ViewModel 中的數據,以便在數據發生變化時自動更新 UI。
  • 使用 Data Binding 來簡化 UI 的更新。
  • 使用 Kotlin 協程來執行異步操作。

選擇哪種方法?

  • 簡單的 Fragment 替換:?使用?replace()?和?addToBackStack()
  • 多個 Fragment 并存,需要控制可見性:?使用?add()hide()?和?show()
  • 滑動切換 Fragment:?使用?ViewPager?和?FragmentPagerAdapter?或?FragmentStatePagerAdapter
  • 復雜的導航結構:?使用 Navigation Component。

總而言之,Activity 動態切換 Fragment 是 Android 開發中一項重要的技能。 選擇合適的方法,并遵循最佳實踐,可以構建靈活、高效和用戶友好的應用。

AskManyAI

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82520.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82520.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82520.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

FreeRTOS Semaphore信號量-筆記

FreeRTOS Semaphore信號量-筆記 **一、信號量與互斥量的核心區別****二、二值信號量(Binary Semaphore)****1. 功能與使用場景****2. 示例:ADC中斷與任務同步** **三、計數信號量(Counting Semaphore)****1. 功能與使用…

音頻類網站或者資訊總結

我愛音頻網: 我愛音頻網 - 我們只談音頻,豐富的TWS真無線藍牙耳機拆解報告 (52audio.com) 其他更多資訊 音頻行業全品類深度剖析,2024市場趨勢解讀匯總-EDN 電子技術設計 (ednchina.com)

16.Excel:數據收集

一 使用在線協作工具 簡道云。 excel的在線表格協作在國內無法使用,而數據采集最需要在線協作。 二 使用 excel 1.制作表格 在使用excel進行數據采集的時候,會制作表頭給填寫人,最好還制作一個示例。 1.輸入提示 當點擊某個單元格的時候&am…

JAVA虛擬機(JVM)總結,很清晰,很好理解!!

目錄 java編譯相關知識 Java文件編譯過程 java的可跨平臺性 JVM內存結構 運行期數據區域(JDK8之后) 本地方法棧 虛擬方法棧 程序計數器 堆 本地內存 棧幀里面的局部變量表和方法區(元空間的區別) 類加載器 啟動類加載…

前端項目中單元測試與集成測試的管理實踐

前端項目中單元測試與集成測試的管理實踐 在現代前端工程化中,單元測試(Unit Test)和集成測試(Integration Test)已成為保障項目質量的重要手段。合理地組織和管理測試代碼,不僅有助于持續集成&#xff0c…

【Redis】緩存和分布式鎖

🔥個人主頁: 中草藥 🔥專欄:【中間件】企業級中間件剖析 一、緩存(Cache) 概述 Redis最主要的應用場景便是作為緩存。緩存(Cache)是一種用于存儲數據副本的技術或組件,…

深入解析路由策略:從流量控制到策略實施

一、網絡流量雙平面解析 在路由策略的設計中,必須明確區分兩個關鍵平面: 1. 控制層面(Control Plane) ??定義??:路由協議傳遞路由信息形成的邏輯平面(如OSPF的LSA、RIP的Response報文)?…

從杰夫?托爾納看 BPLG 公司的技術創新與發展

在科技與商業緊密交織的時代,企業的技術領導者在推動組織前行、應對復雜多變的市場環境中扮演著極為關鍵的角色。《對話 CTO,駕馭高科技浪潮》的第 6 章聚焦于杰夫?托爾納及其所在的 BPLG 公司,為我們展現了一幅技術驅動企業發展的生動圖景&…

UniRepLknet助力YOLOv8:高效特征提取與目標檢測性能優化

文章目錄 一、引言二、UniRepLknet 的框架原理(一)架構概述(二)架構優勢 三、UniRepLknet 在 YOLOv8 中的集成(一)集成方法(二)代碼實例 四、實驗與對比(一)對…

比較Facebook與其他社交平臺的隱私保護策略

在這個數字化的時代,隱私保護已成為用戶和社交平臺共同關注的核心議題。Facebook,作為全球最大的社交網絡平臺之一,其隱私保護策略一直受到廣泛的關注和討論。本文將對Facebook的隱私保護策略與其他社交平臺進行比較,以幫助用戶更…

數據結構--樹

一、樹的概念 樹是由n(n≥0)個節點組成的有限集合,它滿足以下條件: 1. 當n0時,稱為空樹 2. 當n>0時,有且僅有一個特定的節點稱為根節點(root) 3. 其余節點可分為m(m≥0)個互不相交的有限集合,每個集合本身又是一…

Linux `ifconfig` 指令深度解析與替代方案指南

Linux `ifconfig` 指令深度解析與替代方案指南 一、核心功能與現狀1. 基礎作用2. 版本適配二、基礎語法與常用操作1. 標準語法2. 常用操作速查顯示所有接口信息啟用/禁用接口配置IPv4地址修改MAC地址(臨時)三、高級配置技巧1. 虛擬接口創建2. MTU調整3. 多播配置4. ARP控制四…

什么是分布式光伏系統?屋頂分布式光伏如何并網?

政策窗口倒計時!分布式光伏如何破局而立? 2025年,中國分布式光伏行業迎來關鍵轉折: ? "430"落幕——搶裝潮收官,但考驗才剛開始; ? "531"生死線——新增項目全面市場化交易啟動&…

Cluster Interconnect in Oracle RAC

Cluster Interconnect in Oracle RAC (文檔 ID 787420.1)?編輯轉到底部 In this Document Purpose Scope Details Physical Layout of the Private Interconnect Why Do We Need a Private Interconnect ? Interconnect Failure Interconnect High Availability Private Inte…

.Net HttpClient 使用準則

HttpClient 使用準則 System.Net.Http.HttpClient 類用于發送 HTTP 請求以及從 URI 所標識的資源接收 HTTP 響應。 HttpClient 實例是應用于該實例執行的所有請求的設置集合,每個實例使用自身的連接池,該池將其請求與其他請求隔離開來。 從 .NET Core …

【PostgreSQL】數據庫主從庫備份與高可用部署

文章目錄 一、架構設計原理二、部署清單示例2.1 StatefulSet配置片段2.2 Service配置三、配置詳解3.1 主節點postgresql.conf3.2 從節點配置四、初始化流程4.1 創建復制用戶4.2 配置pg_hba.conf五、故障轉移示例5.1 自動切換腳本5.2 手動提升從節點六、監控與維護6.1 關鍵監控指…

JavaScript 數組去重:11 種方法對比與實戰指南

文章目錄 前言一、使用 Set 數據結構二、使用 filter indexOf三、使用 reduce 累加器四、雙重 for 循環五、利用對象屬性唯一性六、先排序后去重七、使用 Map 數據結構八、使用 includes 方法九、優化處理 NaN 的 filter 方法十、利用 findIndex十一.利用Set和展開運算符處理多…

ai agent(智能體)開發 python3基礎14:在python 中 總能看到方法里面套方法,那什么時候用這種方式合適呢?

讓人頭疼的方法嵌套還是要去了解的 在 Python 中,方法內部嵌套方法(即在類的方法中定義另一個函數)是一種常見的代碼組織技巧,它可以在特定場景下帶來以下好處: 1. 代碼復用與邏輯封裝 如果某個方法內部有重復的邏輯…

Yocto項目實戰經驗總結:從入門到高級的全面概覽

本文面向開發者和實際項目經驗者,分享經過大量實戰積累的 Yocto 項目工程經驗和基礎技巧。本文簡明但精彩,應用和觀察相結合,充分適合做為全面進階 Yocto 項目開發的實用指南。 一、入門理解:Yocto 是什么?規劃如何開始…

添加物體.

在cesium中我們可以添加物體進入地圖.我們以廣州塔為例 //生成廣州塔的位置var position2 Cesium.Cartesian3.fromDegrees(113.3191,23.109,100)viewer.camera.setView({//指定相機位置destination: position2, 運行后如圖 我們使用cesium官網提供的代碼為廣州塔在地圖上標點…