Android Fragment建立、更換、尋找、Back Stack

Fragment的方法有很多種,在我看官方手冊前,也使用與官方不同的方式

本文是以官方的方式做為介紹

以下內容參考於 Android 官網

1. 使用XML在Activity與Fragment連接

2. 使用程式方式在Activity與Fragment連接

3. 將已新增的Fragment更換

4. 尋找已建立的Fragment

5. Fragment對應的FragmentManager

6. Back Stack使用

使用前準備

在Project build.gradle

buildscript {
    ...
    ext.fragment_version = "1.3.6"
    ...
}

在app build.gradle

dependencies {
    ...
    // Java language implementation
    implementation("androidx.fragment:fragment:$fragment_version")
    // Kotlin
    implementation("androidx.fragment:fragment-ktx:$fragment_version")
    ...
}

1. XML在Activity與Fragment連接

透過android:name與指定的Fragment做連接

以下是Activity Layout

<androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:name="com.example.myapplication.fragment.TestFragment1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/layout"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

2. 使用程式方式在Activity與Fragment連接

以下是Activity Layout

<androidx.fragment.app.FragmentContainerView
    android:id="@+id/fragment_container_view"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toTopOf="@+id/layout"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"/>

以下是程式連結Fragment方法

備註:You should always use setReorderingAllowed(true) when performing a FragmentTransaction.

這部分之後會有文章解釋

//Activity
val bundle = bundleOf("data" to 1234)
supportFragmentManager.commit {
    setReorderingAllowed(true)
    add<TestFragment1>(R.id.fragment_container_view, args = bundle)
}

//TestFragment1
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val someInt = requireArguments().getInt("data")
    println("someInt $someInt")//打印someInt 1234
}

3. 將已新增的Fragment更換

supportFragmentManager.commit {
    setReorderingAllowed(true)
    add<TestFragment1>(
        R.id.fragment_container_view
    )
}
supportFragmentManager.commit {
    setReorderingAllowed(true)
    replace<TestFragment2>(
        R.id.fragment_container_view
    )
}

4. 尋找已建立的Fragment

以下是用findFragmentById,找到指定的Fragment

按下buttonA會打印testFun

//Activity
supportFragmentManager.commit {
    setReorderingAllowed(true)
    add<TestFragment1>(R.id.fragment_container_view, args = bundle)
}

binding.buttonA.setOnClickListener {
    val testFragment1 = supportFragmentManager
        .findFragmentById(R.id.fragment_container_view) as TestFragment1
    testFragment1.testFun()
}

//TestFragment1
fun testFun() {
    println("testFun")
}

以下是用findFragmentByTag,找到指定的Fragment

按下buttonB會打印testFun

val bundle = bundleOf("data" to 1234)
supportFragmentManager.commit {
    setReorderingAllowed(true)
    add<TestFragment1>(
        R.id.fragment_container_view, 
        args = bundle, 
        tag = "test1"
    )
}

binding.buttonB.setOnClickListener {
    val testFragment1 = supportFragmentManager
        .findFragmentByTag("test1") as TestFragment1
    testFragment1.testFun()
}


//TestFragment1
fun testFun() {
    println("testFun")
}

5. Fragment對應的FragmentManager

6. Back Stack使用

備註:如果沒事先用addToBackStack,popBackStack將不會有反應

//測試1 add 2個fragment
//第二個+addToBackStack(null)
//點兩次buttonB,會發現只有返回一次,TestFragment1並無反應
supportFragmentManager.commit {
    setReorderingAllowed(true)
    add<TestFragment1>(
        R.id.fragment_container_view
    )
}
supportFragmentManager.commit {
    setReorderingAllowed(true)
    add<TestFragment2>(
        R.id.fragment_container_view
    )
    addToBackStack(null)
}
binding.buttonB.setOnClickListener {
    //supportFragmentManager.popBackStack() 與 
    //supportFragmentManager.popBackStack(null,0)相同功能
    supportFragmentManager.popBackStack(null,0)
}
//測試2 add 2個fragment
//二個都+addToBackStack(null)
//點兩次buttonB,會發現只有返回二次
supportFragmentManager.commit {
    setReorderingAllowed(true)
    add<TestFragment1>(
        R.id.fragment_container_view
    )
    addToBackStack(null)
}
supportFragmentManager.commit {
    setReorderingAllowed(true)
    add<TestFragment2>(
        R.id.fragment_container_view
    )
    addToBackStack(null)
}
binding.buttonB.setOnClickListener {
    //supportFragmentManager.popBackStack() 與 
    //supportFragmentManager.popBackStack(null,0)相同功能
    supportFragmentManager.popBackStack(null,0)
}
//測試3 add 2個fragment
//第一個+addToBackStack("123")
//第二個+addToBackStack("456")
//不管點幾次都只會把第二個彈出
supportFragmentManager.commit {
    setReorderingAllowed(true)
    add<TestFragment1>(
        R.id.fragment_container_view
    )
    addToBackStack("123")
}
supportFragmentManager.commit {
    setReorderingAllowed(true)
    add<TestFragment2>(
        R.id.fragment_container_view
    )
    addToBackStack("456")
}
binding.buttonB.setOnClickListener {
    supportFragmentManager.popBackStack("456",POP_BACK_STACK_INCLUSIVE)
}
//測試4 add 2個fragment
//第一個+addToBackStack("456")
//第二個+addToBackStack("456")
//點一次就會把第二個"都"彈出
supportFragmentManager.commit {
    setReorderingAllowed(true)
    add<TestFragment1>(
        R.id.fragment_container_view
    )
    addToBackStack("456")
}
supportFragmentManager.commit {
    setReorderingAllowed(true)
    add<TestFragment2>(
        R.id.fragment_container_view
    )
    addToBackStack("456")
}
binding.buttonB.setOnClickListener {
    supportFragmentManager.popBackStack("456",POP_BACK_STACK_INCLUSIVE)
}

相關文章

Android Fragment add與replace分析Android Fragment 自定義constructor
1. 重寫FragmentFactory
2. 建立Fragment
3. 在Activity中使用
Android Fragment show、hide、attach、detach用法Android Fragment Transitions動畫效果
1. 範例程式
2. Fragment show與hide是什麼呢?
3. Fragment attach與detach是什麼呢?
1. 範例程式
2. 功能介紹
Android Fragment shared element transitions動畫效果Android Fragment lifecycle
1. 範例程式
2. 功能介紹
1. 簡略
2. 測試搭配setMaxLifecycle的生命週期
Android Fragment通訊
1. 簡要
2. 使用View Model共享數據
3. 使用 Fragment Result API獲取結果

訂閱Codeilin的旅程,若有最新消息會通知。

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

WordPress.com.

向上 ↑

%d 位部落客按了讚: