片段代表的是在一個活動中使用者介面裡模組的部分。片段具有其生命週期、會接收其本身的輸入事件,而在其具有的活動執行時,您可以新增或移除片段。
本文件將說明如何建立片段,並將其納入活動中。
設定環境
片段需要一個 AndroidX 片段程式庫的依附元件。您必須將 Google Maven 存放區新增至專案的 settings.gradle
檔案中,才能納入這個依附元件。
Groovy
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() ... } }
Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() ... } }
若要在專案中納入 AndroidX 片段程式庫,請在應用程式的 build.gradle
檔案中新增以下依附元件:
Groovy
dependencies { def fragment_version = "1.8.2" // Java language implementation implementation "androidx.fragment:fragment:$fragment_version" // Kotlin implementation "androidx.fragment:fragment-ktx:$fragment_version" }
Kotlin
dependencies { val fragment_version = "1.8.2" // Java language implementation implementation("androidx.fragment:fragment:$fragment_version") // Kotlin implementation("androidx.fragment:fragment-ktx:$fragment_version") }
建立片段類別
若要建立一個片段,請擴充 AndroidX Fragment
類別,並覆寫其方法,插入應用程式的邏輯,做法與建立 Activity
類別類似。若要建立一個用來定義其專屬版面配置的最小片段,請為基礎建構函式提供片段的版面配置資源,作法如以下範例所示:
Kotlin
class ExampleFragment : Fragment(R.layout.example_fragment)
Java
class ExampleFragment extends Fragment { public ExampleFragment() { super(R.layout.example_fragment); } }
Fragment 程式庫也提供較為特殊的片段基礎類別:
DialogFragment
- 顯示浮動對話方塊。除了使用
Activity
類別的對話方塊輔助方法以外,運用這個類別建立對話方塊是很不錯的替代方法,因為片段會自動處理Dialog
的建立及清理作業。詳細內容請參閱透過DialogFragment
顯示對話方塊。 PreferenceFragmentCompat
- 以清單的形式顯示
Preference
物件的階層清單。您可以使用PreferenceFragmentCompat
為應用程式建立設定畫面。
在活動中新增片段
一般來說,片段必須嵌入在 AndroidX FragmentActivity
中,才能為該活動的版面配置提供部分使用者介面。FragmentActivity
是 AppCompatActivity
的基礎類別,因此若您已將 AppCompatActivity
設為子類別,用來在應用程式中提供回溯相容性,就不必變更活動的基礎類別。
您可以將片段新增至活動的檢視區塊階層,方法是在活動的版面配置檔案中定義片段;或是在活動的版面配置檔案中定義片段容器,然後以程式輔助方式從活動中新增片段。無論是哪一種作法,您都必須新增 FragmentContainerView
,以定義片段在活動的檢視區塊階層中的位置。強烈建議您一律使用 FragmentContainerView
做為片段的容器,因為 FragmentContainerView
具有特別針對片段的修正內容,而這是其他檢視區塊群組(例如 FrameLayout
)所沒有的。
透過 XML 新增片段
如果要對活動版面配置的 XML 宣告新增片段,請使用 FragmentContainerView
元素。
以下是含有單一 FragmentContainerView
的活動版面配置範例:
<!-- res/layout/example_activity.xml -->
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.ExampleFragment" />
android:name
屬性可指定 Fragment
的類別名稱以用來執行個體化。當系統載入活動的版面配置時,指定的片段就會執行個體化;新執行個體化的片段中 onInflate()
會被呼叫,接著會建立 FragmentTransaction
將片段新增至 FragmentManager
。
透過程式輔助方式新增片段
如要透過程式輔助方式在活動的版面配置中新增片段,則版面配置應包含 FragmentContainerView
做為片段的容器,如以下範例所示:
<!-- res/layout/example_activity.xml -->
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
與 XML 作法不同的是,FragmentContainerView
中沒有使用到 android:name
屬性,因此沒有特定的片段會自動執行個體化。反之,FragmentTransaction
則被用來將片段執行個體化,並將其新增至活動的版面配置中。
活動執行時,可以對片段進行交易,例如新增、移除或取代片段。您可以在 FragmentActivity
中取得 FragmentManager
的例項,可用於建立 FragmentTransaction
。接著,您可以使用 FragmentTransaction.add()
,在活動的 onCreate()
方法中將片段例項化,傳入版面配置中容器的 ViewGroup
ID,以及您要新增的片段類別;然後才提交交易。如以下範例所示:
Kotlin
class ExampleActivity : AppCompatActivity(R.layout.example_activity) { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (savedInstanceState == null) { supportFragmentManager.commit { setReorderingAllowed(true) add<ExampleFragment>(R.id.fragment_container_view) } } } }
Java
public class ExampleActivity extends AppCompatActivity { public ExampleActivity() { super(R.layout.example_activity); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .setReorderingAllowed(true) .add(R.id.fragment_container_view, ExampleFragment.class, null) .commit(); } } }
在前一個範例中,請注意,只有當 savedInstanceState
為 null
時,才會建立片段交易。這是為了確保在首次建立活動時,只會新增一次片段。當設定變更而且重新建立了活動時,savedInstanceState
不再是 null
,且不必再次新增片段,因為片段會自動從 savedInstanceState
中還原。
如果片段需要一些初始資料,可以在呼叫 FragmentTransaction.add()
時提供 Bundle
將引數傳送至片段,如下所示:
Kotlin
class ExampleActivity : AppCompatActivity(R.layout.example_activity) { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (savedInstanceState == null) { val bundle = bundleOf("some_int" to 0) supportFragmentManager.commit { setReorderingAllowed(true) add<ExampleFragment>(R.id.fragment_container_view, args = bundle) } } } }
Java
public class ExampleActivity extends AppCompatActivity { public ExampleActivity() { super(R.layout.example_activity); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { Bundle bundle = new Bundle(); bundle.putInt("some_int", 0); getSupportFragmentManager().beginTransaction() .setReorderingAllowed(true) .add(R.id.fragment_container_view, ExampleFragment.class, bundle) .commit(); } } }
接著透過呼叫 requireArguments()
從片段中擷取引數 Bundle
,並使用適當的 Bundle
getter 方法擷取每個引數。
Kotlin
class ExampleFragment : Fragment(R.layout.example_fragment) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val someInt = requireArguments().getInt("some_int") ... } }
Java
class ExampleFragment extends Fragment { public ExampleFragment() { super(R.layout.example_fragment); } @Override public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { int someInt = requireArguments().getInt("some_int"); ... } }
另請參閱
片段交易,FragmentManager
則會在片段管理員指南中詳細說明。