Fragment 的簡單用法
Fragment 是一種可以嵌入在 Activity 當中的 UI 片段,它能讓程式更加合理和充分地利用大螢屏的空間,因此在平板上應用非常廣泛
在一個 Activity 中添加兩個 Fragment,并讓兩個 Fragment 平分 Activity 的空間,首先新建一個左側 Fragment 的布局 left_fragment.xml,這個布局只放置了一個按鈕
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Button" />
</LinearLayout>
然后新建一個右側 Fragment 的布局 right_fragment.xml,將背景色設定成綠色,并放置一個 TextView 用于顯示一段文本
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#00ff00"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="24sp"
android:text="This is right fragment" />
</LinearLayout>
接著新建一個 LeftFragment 類,并讓它繼承自 Fragment,注意這里要使用 AndroidX 庫中的 Fragment,將剛剛定義的兩個布局動態加載進來
class LeftFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.left_fragment, container, false)
}
}
class RightFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.right_fragment, container, false)
}
}
接下來修改 activity_main.xml 中的代碼,使用 <fragment> 標簽在布局中添加 Fragment
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/leftFrag"
android:name="com.example.fragmenttest.LeftFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<fragment
android:id="@+id/rightFrag"
android:name="com.example.fragmenttest.RightFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>

動態加載 Fragment
Fragment 真正強大之處在于,它可以在程式運行時根據具體情況來動態添加 Fragment,使得程式界面更加多樣化
修改 activity_main.xml 的代碼,使用 FrameLayout 布局,所有的空間都會默認擺放在布局的左上角,由于這里僅需要在布局里放入一個 Fragment,不需要任何定位,因此適合使用 FragLayout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/leftFrag"
android:name="com.example.fragmenttest.LeftFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="@+id/rightLayout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
修改 MainActivity 中的代碼,實作動態添加 Fragment 的功能,給左側 Fragment 的按鈕注冊一個點擊事件,會動態加載右側 Fragment
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
replaceFragment(RightFragment())
}
}
private fun replaceFragment(fragment: Fragment) {
val fragmentManager = supportFragmentManager
val transaction = fragmentManager.beginTransaction()
transaction.replace(R.id.rightLayout, fragment)
transaction.commit()
}
}


Fragment 實作回傳堆疊
在上一節,通過點擊按鈕加載一個 Fragment 之后,按下 Back 鍵程式就會直接退出,如果我們希望實作類似回傳堆疊的效果,按下 Back 鍵可以回傳
FragmentTransaction 中提供了一個 addToBackStack() 方法,可以用于將一個事務添加到回傳堆疊中,修改 MainActivity 中的代碼
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
replaceFragment(RightFragment())
}
}
private fun replaceFragment(fragment: Fragment) {
val fragmentManager = supportFragmentManager
val transaction = fragmentManager.beginTransaction()
transaction.replace(R.id.rightLayout, fragment)
transaction.addToBackStack(null)
transaction.commit()
}
}
我們在事務提交之前呼叫了 FragmentTransaction 的 addToBackStack() 方法,它可以接收一個名字用于描述回傳堆疊的狀態,一般傳入 null 即可,現在重新運行程式,點擊按鈕加載右側 Fragment,然后按下 Back 鍵,程式不會立刻退出,而是回傳上一狀態
Fragment 和 Activity 之間的互動
為了方便 Fragment 和 Activity 之間進行互動,FragmentManager 提供了一個類似于 findViewById() 的方法,專門用于從布局檔案中獲取 Fragment 的實體
supportFragmentManager.findFragmentById(R.id.leftFrag) as LeftFragment
那么在 Fragment 中又該怎么呼叫 Activity 里的方法呢?在每個 Fragment 中都可以通過呼叫 getActivity() 方法來得到和當前 Fragment 相關聯的 Activity 實體
if (activity != null) {
val mainActivity = activity as MainActivity
}
不同的 Fragment 之間也可以通信,基本思路是:首先在一個 Fragment 中得到與它相關聯的 Activity,然后再通過這個 Activity 去獲取另外一個 Fragment 實體,就實作了不同的 Fragment 之間的通信了
Fragment 生命周期
和 Activity 一樣,Fragment 也有自己的生命周期,并且大體一致,只不過在一些細小的地方會有部磁區別:
-
運行狀態
當一個 Fragment 所關聯的 Activity 正處于運行狀態,該 Fragment 也處于運行狀態
-
暫停狀態
當一個 Activity 進入暫停狀態(由于另一個未占滿的 Activity 被添加到了堆疊頂),與它相關聯的 Fragment 就會進入暫停狀態
-
停止狀態
當一個 Activity 進入停止狀態,與它相關聯的 Fragment 就會進入停止狀態,或者通過呼叫 FragmentTransaction 的 remove()、replace() 方法將 Fragment 從 Activity 中移除,但在事務提交前呼叫了 addToBackStack() 方法,也會進入停止狀態
-
銷毀狀態
當 Activity 被銷毀時,與它相關聯的 Fragment 就會進入銷毀狀態,或者通過呼叫 FragmentTransaction 的 remove()、replace() 方法將 Fragment 從 Activity 中移除,但在事務提交前沒有呼叫了 addToBackStack() 方法,也會進入銷毀狀態
Fragment 完整的生命周期可參考下圖

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/306450.html
標籤:其他
上一篇:Android隱藏選單欄
