室內(nèi)環(huán)保網(wǎng)站模板代碼seo網(wǎng)站優(yōu)化培訓(xùn)怎么做
1.碎片(Fragment)是什么
Fragment是依賴于Activity的,不能獨(dú)立存在的,是Activity界面中的一部分,可理解為模塊化的Activity,它能讓程序更加合理和充分地利用大屏幕的空間,因而在平板上應(yīng)用得非常廣泛.
- Fragment不能獨(dú)立存在,必須嵌入到Activity中
- Fragment具有自己的生命周期,接收它自己的事件,并可以在Activity運(yùn)行時(shí)被添加或刪除
- Fragment的生命周期直接受所在的Activity的影響。如:當(dāng)Activity暫停時(shí),它擁有的所有Fragment們都暫停
那么究竟要如何使用碎片才能充分地利用平板屏幕的空間呢?想象我們正在開發(fā)一個(gè)新聞應(yīng)用,其中一個(gè)界面使用RecyclerView展示了一組新聞的標(biāo)題,當(dāng)點(diǎn)擊了其中一個(gè)標(biāo)題時(shí),就打開另一個(gè)界面顯示新聞的詳細(xì)內(nèi)容。如果是在手機(jī)中設(shè)計(jì),我們可以將新聞標(biāo)題列表放在一個(gè)活動(dòng)中,將新聞的詳細(xì)內(nèi)容放在另一個(gè)活動(dòng)中.
可是如果在平板上也這么設(shè)計(jì),那么新聞標(biāo)題列表將會(huì)被拉長(zhǎng)至填充滿整個(gè)平板的屏幕,而新聞的標(biāo)題一般都不會(huì)太長(zhǎng),這樣將會(huì)導(dǎo)致界面上有大量的空白區(qū)域.
因此,更好的設(shè)計(jì)方案是將新聞標(biāo)題列表界面和新聞詳細(xì)內(nèi)容界面分別放在兩個(gè)碎片中,然后在同一個(gè)活動(dòng)里引入這兩個(gè)碎片,這樣就可以將屏幕空間充分地利用起來(lái)了.
2. 碎片的簡(jiǎn)單用法
這里我們準(zhǔn)備先寫一個(gè)最簡(jiǎn)單的碎片示例來(lái)練練手,在一個(gè)活動(dòng)當(dāng)中添加兩個(gè)碎片,并讓這兩個(gè)碎片平分活動(dòng)空間。
新建一個(gè)左側(cè)碎片布局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"><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="Button"/></LinearLayout>
這個(gè)布局非常簡(jiǎn)單,只放置了一個(gè)按鈕,并讓它水平居中顯示。然后新建右側(cè)碎片布局right_fragment.xml,代碼如下
<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"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:textSize="20sp"android:text="This is right fragment"/></LinearLayout>
可以看到,我們將這個(gè)布局的背景色設(shè)置成了綠色,并放置了一個(gè)TextView用于顯示一段文本。
接著新建一個(gè)LeftFragment 類,并讓它繼承自Fragment,現(xiàn)在編寫一下LeftFragment 中的代碼
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import androidx.fragment.app.Fragment;public class LeftFragment extends Fragment {public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View view = inflater.inflate(R.layout.left_frame, container, false);return view;}}
這里僅僅是重寫了Fragment的onCreateView()方法,然后在這個(gè)方法中通過(guò)LayoutInflater的inflate()方法將剛才定義的left_fragment布局動(dòng)態(tài)加載進(jìn)活動(dòng)中來(lái),整個(gè)方法簡(jiǎn)單明了。
那么問(wèn)題來(lái)了,上面所提到的,將自己對(duì)應(yīng)的布局文件left_fragment.xml以及right_fragment.xml加載進(jìn)來(lái),那什么時(shí)候加載進(jìn)來(lái)呢?這個(gè)問(wèn)題在碎片布局的引入執(zhí)行邏輯一章中再進(jìn)行回答。
接著我們用同樣的方法再新建一個(gè)RightFragment ,代碼如下所示:
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import androidx.fragment.app.Fragment;public class RightFragment extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View view = inflater.inflate(R.layout.right_fragment, container, false);return view;}}
基本上代碼都是相同的,相信已經(jīng)沒有必要再做什么解釋了。新版android怎么添加Fragment
接下來(lái)看activity_main.xml中的代碼
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent" ><fragmentandroid:id="@+id/left_fragment"android:name="com.example.fragmenttest.LeftFragment"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1" tools:layout="@layout/left_fragment"/><fragmentandroid:id="@+id/right_fragment"android:name="com.example.fragmenttest.RightFragment"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1" tools:layout="@layout/right_fragment"/></LinearLayout>
可以看到,我們使用了<fragment>
標(biāo)簽在布局中添加碎片,其中指定的大多數(shù)屬性都是你熟悉的,只不過(guò)這里還需要通過(guò)android:name 屬性來(lái)顯式指明要添加的碎片類名,注意一定要將類的包名也加上(因?yàn)椴患由暇筒恢来薴ragment標(biāo)簽是由哪一個(gè)類實(shí)現(xiàn)的),最后要加上tools:layout=""XXX"。?
運(yùn)行結(jié)果:
?2.1?碎片布局引入活動(dòng)的程序執(zhí)行邏輯
?
現(xiàn)在可以回答上述問(wèn)題了,究竟何時(shí)何地加載了兩個(gè)碎片布局。由于我們?cè)贛ainActivity方法中調(diào)用了方法:setContentView(R.layout.activity_main);所以只會(huì)加載布局文件activity_main.xml,而我們?cè)诖瞬季治募刑砑恿藘蓚€(gè)fragment控件,而實(shí)際上其通過(guò):android:name="com.example.fragmenttest.LeftFragment"指向了類文件:LeftFragment.java,(我們不是通過(guò)android:id="@+id/left_fragment"知道這個(gè)碎片控件實(shí)現(xiàn)類是誰(shuí),而是android:name來(lái)控制的),而類文件LeftFragment.java則重寫了方法onCreateView(),使其返回一個(gè)我們所指定的的布局View對(duì)象,而這個(gè)對(duì)象是由R.layout.left_fragment指向了:left_fragment.xml。
所以執(zhí)行邏輯可以認(rèn)為是大致如下:
MainActivity#onCreate -> activity_main.xml -> <fragment>-> <fragment>標(biāo)簽中的android:name -> LeftFragment類 ->LayoutInflater#inflate(int, android.view.ViewGroup, boolean)方法 -> left_fragment.xml -> right_fragment同理。
?可以發(fā)現(xiàn)實(shí)際上上述代碼執(zhí)行順序和我們寫代碼的順序是完全相反的,我們首先要寫一個(gè)關(guān)于fragment的布局xml文件,接著創(chuàng)建一個(gè)碎片類去引用這個(gè)布局文件,最后第二步是在activity_main文件中通過(guò)android:name來(lái)引用這個(gè)碎片類,最后才是在MainActivity中加載activity_main布局??梢哉f(shuō)這樣寫代碼的好處是不會(huì)IDE是不會(huì)報(bào)錯(cuò)引用錯(cuò)誤,壞處是和程序的執(zhí)行順序正好相反,但是如果你深諳代碼的執(zhí)行邏輯,首先就是在activity_main文件中通過(guò)android:name來(lái)引用這個(gè)碎片類,一步步你想思維,我想可能也是一個(gè)寫Android代碼的好思維方式。
3.動(dòng)態(tài)添加碎片
在上一節(jié)當(dāng)中,你已經(jīng)學(xué)會(huì)了在布局文件中添加碎片的方法,不過(guò)碎片真正的強(qiáng)大之處在于,它可以在程序運(yùn)行時(shí)動(dòng)態(tài)地添加到活動(dòng)當(dāng)中。根據(jù)具體情況來(lái)動(dòng)態(tài)地添加碎片,你就可以將程序界面定制得更加多樣化。
我們還是在上一節(jié)代碼的基礎(chǔ)上繼續(xù)完善,新建another_right_fragment.xml,代碼如下
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:background="#ffff00"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:textSize="20sp"android:text="This is another right fragment"/></LinearLayout>
?這個(gè)布局文件的代碼和right_fragment.xml中的代碼基本相同,只是將背景色改成了黃色,并將顯示的文字改了改。然后新建AnotherRightFragment 作為另一個(gè)右側(cè)碎片,代碼如下
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import androidx.fragment.app.Fragment;public class AnotherRightFragment extends Fragment {public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View view = inflater.inflate(R.layout.another_right_fragment, container, false);return view;}
}
代碼同樣非常簡(jiǎn)單,在onCreateView() 方法中加載了剛剛創(chuàng)建的another_right_fragment布局。這樣我們就準(zhǔn)備好了另一個(gè)碎片,接下來(lái)看一下如何將它動(dòng)態(tài)地添加到活動(dòng)當(dāng)中。修改activity_main.xml,代碼如下
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:orientation="horizontal"android:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent" ><androidx.fragment.app.FragmentContainerViewandroid:id="@+id/fragmentContainerView"android:name="com.example.myapplication.LeftFragment"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"tools:layout="@layout/left_fragment" /><FrameLayoutandroid:id="@+id/right_layout"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1" ></FrameLayout><!-- <androidx.fragment.app.FragmentContainerView-->
<!-- android:id="@+id/fragmentContainerView2"-->
<!-- android:name="com.example.myapplication.RightFragment"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="match_parent"-->
<!-- android:layout_weight="1"-->
<!-- tools:layout="@layout/right_frame" />-->
</LinearLayout>
?
可以看到,現(xiàn)在將右側(cè)碎片替換成了一個(gè)FrameLayout中,還記得這個(gè)布局嗎?在上一章中我們學(xué)過(guò),這是Android中最簡(jiǎn)單的一種布局,所有的控件默認(rèn)都會(huì)擺放在布局的左上角**。由于這里僅需要在布局里放入一個(gè)碎片,不需要任何定位,因此非常適合使用FrameLayout**。
?下面我們將在代碼中向FrameLayout里添加內(nèi)容,從而實(shí)現(xiàn)動(dòng)態(tài)添加碎片的功能。修改MainActivity中的代碼,如下所示
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;public class MainActivity extends AppCompatActivity{boolean signal = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);replaceFragment(new RightFragment());signal = true;ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});}private void replaceFragment(Fragment fragment) {FragmentManager fragmentManager = getSupportFragmentManager();FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.replace(R.id.right_layout,fragment);transaction.addToBackStack(null);transaction.commit();}public void key_click(View view) {Log.d("MainActivity","button is clicked");if(signal == true){replaceFragment(new AnotherRightFragment());signal = false;}else {replaceFragment(new RightFragment());signal = true;}Toast.makeText(MainActivity.this,"方法2 點(diǎn)擊按鍵",Toast.LENGTH_SHORT).show();}
}
?可以看到,首先我們給左側(cè)碎片中的按鈕注冊(cè)了一個(gè)點(diǎn)擊事件(直接在left_fragment.xml直接生成onclick),然后調(diào)用replaceFragment() 方法動(dòng)態(tài)添加了RightFragment這個(gè)碎片。當(dāng)點(diǎn)擊左側(cè)碎片中的按鈕時(shí),又會(huì)調(diào)用replaceFragment() 方法將右側(cè)碎片替換成AnotherRightFragment。結(jié)合replaceFragment() 方法中的代碼可以看出,動(dòng)態(tài)添加碎片主要分為5步。
- 創(chuàng)建待添加的碎片實(shí)例。
- 獲取FragmentManager,在活動(dòng)中可以直接通過(guò)調(diào)用getSupportFragmentManager() 方法得到。
- 開啟一個(gè)事務(wù),通過(guò)調(diào)用beginTransaction() 方法開啟。
- 向容器內(nèi)添加或替換碎片,一般使用replace() 方法實(shí)現(xiàn),需要傳入容器的id和待添加的碎片實(shí)例。
- 提交事務(wù),調(diào)用commit() 方法來(lái)完成。
?這樣就完成了在活動(dòng)中動(dòng)態(tài)添加碎片的功能,重新運(yùn)行程序,可以看到和之前相同的界面,然后點(diǎn)擊一下按鈕,按BUTTON一下就會(huì)使右邊的兩個(gè)布局切換
4.?在碎片中模擬返回棧?
????????在上一小節(jié)中,我們成功實(shí)現(xiàn)了向活動(dòng)中動(dòng)態(tài)添加碎片的功能,不過(guò)你嘗試一下就會(huì)發(fā)現(xiàn),通過(guò)點(diǎn)擊按鈕添加了一個(gè)碎片之后,這時(shí)按下Back鍵程序就會(huì)直接退出。如果這里我們想模仿類似于返回棧的效果,按下Back鍵可以回到上一個(gè)碎片,該如何實(shí)現(xiàn)呢?
????????其實(shí)很簡(jiǎn)單,FragmentTransaction中提供了一個(gè)addToBackStack() 方法,可以用于將一個(gè)事務(wù)添加到返回棧中,修改MainActivity中的代碼,如下所示
private void replaceFragment(Fragment fragment) {FragmentManager fragmentManager = getSupportFragmentManager();FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.replace(R.id.right_layout, fragment);transaction.addToBackStack(null);transaction.commit();}
????????這里我們?cè)谑聞?wù)提交之前調(diào)用了FragmentTransaction的addToBackStack() 方法,它可以接收一個(gè)名字用于描述返回棧的狀態(tài),一般傳入null 即可?,F(xiàn)在重新運(yùn)行程序,并點(diǎn)擊按鈕將AnotherRightFragment添加到活動(dòng)中,然后按下Back鍵,你會(huì)發(fā)現(xiàn)程序并沒有退出,而是回到了RightFragment界面,繼續(xù)按下Back鍵,RightFragment界面也會(huì)消失,再次按下Back鍵,程序才會(huì)退出.
5.碎片和活動(dòng)之間進(jìn)行通信
雖然碎片都是嵌入在活動(dòng)中顯示的,可是實(shí)際上它們的關(guān)系并沒有那么親密。你可以看出,碎片和活動(dòng)都是各自存在于一個(gè)獨(dú)立的類當(dāng)中的,它們之間并沒有那么明顯的方式來(lái)直接進(jìn)行通信。如果想要在活動(dòng)中調(diào)用碎片里的方法,或者在碎片中調(diào)用活動(dòng)里的方法,應(yīng)該如何實(shí)現(xiàn)呢?
?為了方便碎片和活動(dòng)之間進(jìn)行通信,FragmentManager提供了一個(gè)類似于findViewById() 的方法,專門用于從布局文件中獲取碎片的實(shí)例,代碼如下
RightFragment rightFragment = getSupportFragmentManager().findFragmentById(R.id.right_fragment);
調(diào)用FragmentManager的findFragmentById() 方法,可以在活動(dòng)中得到相應(yīng)碎片的實(shí)例,然后就能輕松地調(diào)用碎片里的方法了。
?掌握了如何在活動(dòng)中調(diào)用碎片里的方法,那在碎片中又該怎樣調(diào)用活動(dòng)里的方法呢?其實(shí)這就更簡(jiǎn)單了,在每個(gè)碎片中都可以通過(guò)調(diào)用getActivity() 方法來(lái)得到和當(dāng)前碎片相關(guān)聯(lián)的活動(dòng)實(shí)例,代碼如下
MainActivity activity = getActivity();
有了活動(dòng)實(shí)例之后,在碎片中調(diào)用活動(dòng)里的方法就變得輕而易舉了。另外當(dāng)碎片中需要使用Context 對(duì)象時(shí),也可以使用getActivity() 方法,因?yàn)楂@取到的活動(dòng)本身就是一個(gè)Context 對(duì)象。
????????這時(shí)不知道你心中會(huì)不會(huì)產(chǎn)生一個(gè)疑問(wèn):既然碎片和活動(dòng)之間的通信問(wèn)題已經(jīng)解決了,那么碎片和碎片之間可不可以進(jìn)行通信呢?
????????說(shuō)實(shí)在的,這個(gè)問(wèn)題并沒有看上去那么復(fù)雜,它的基本思路非常簡(jiǎn)單,首先在一個(gè)碎片中可以得到與它相關(guān)聯(lián)的活動(dòng),然后再通過(guò)這個(gè)活動(dòng)去獲取另外一個(gè)碎片的實(shí)例,這樣也就實(shí)現(xiàn)了不同碎片之間的通信功能,因此這里我們的答案是肯定的。
6.碎片的生命周期
6.1?碎片的狀態(tài)和回調(diào)
????????還記得每個(gè)活動(dòng)在其生命周期內(nèi)可能會(huì)有哪幾種狀態(tài)嗎?沒錯(cuò),一共有運(yùn)行狀態(tài)、暫停狀態(tài)、停止?fàn)顟B(tài)和銷毀狀態(tài)這4種。類似地,每個(gè)碎片在其生命周期內(nèi)也可能會(huì)經(jīng)歷這幾種狀態(tài),只不過(guò)在一些細(xì)小的地方會(huì)有部分區(qū)別。
- 運(yùn)行狀態(tài):當(dāng)一個(gè)碎片是可見的,并且它所關(guān)聯(lián)的活動(dòng)正處于運(yùn)行狀態(tài)時(shí),該碎片也處于運(yùn)行狀態(tài)。
- 暫停狀態(tài):當(dāng)一個(gè)活動(dòng)進(jìn)入暫停狀態(tài)時(shí)(由于另一個(gè)未占滿屏幕的活動(dòng)被添加到了棧頂),與它相關(guān)聯(lián)的可見碎片就會(huì)進(jìn)入到暫停狀態(tài)。
- 停止?fàn)顟B(tài):當(dāng)一個(gè)活動(dòng)進(jìn)入停止?fàn)顟B(tài)時(shí),與它相關(guān)聯(lián)的碎片就會(huì)進(jìn)入到停止?fàn)顟B(tài),或者通過(guò)調(diào)用FragmentTransaction的remove() 、replace() 方法將碎片從活動(dòng)中移除,但如果在事務(wù)提交之前調(diào)用addToBackStack() 方法,這時(shí)的碎片也會(huì)進(jìn)入到停止?fàn)顟B(tài)??偟膩?lái)說(shuō),進(jìn)入停止?fàn)顟B(tài)的碎片對(duì)用戶來(lái)說(shuō)是完全不可見的,有可能會(huì)被系統(tǒng)回收。
- 銷毀狀態(tài):碎片總是依附于活動(dòng)而存在的,因此當(dāng)活動(dòng)被銷毀時(shí),與它相關(guān)聯(lián)的碎片就會(huì)進(jìn)入到銷毀狀態(tài)?;蛘咄ㄟ^(guò)調(diào)用FragmentTransaction的remove() 、replace() 方法將碎片從活動(dòng)中移除,但在事務(wù)提交之前并沒有調(diào)用addToBackStack() 方法,這時(shí)的碎片也會(huì)進(jìn)入到銷毀狀態(tài)。
?結(jié)合之前的活動(dòng)狀態(tài),相信你理解起來(lái)應(yīng)該毫不費(fèi)力吧。同樣地,Fragment 類中也提供了一系列的回調(diào)方法,以覆蓋碎片生命周期的每個(gè)環(huán)節(jié)。其中,活動(dòng)中有的回調(diào)方法,碎片中幾乎都有,不過(guò)碎片還提供了一些附加的回調(diào)方法,那我們就重點(diǎn)看一下這幾個(gè)回調(diào)。
- onAttach():Fragment與Activity關(guān)聯(lián)時(shí)調(diào)用。
- onCreate():創(chuàng)建Fragment時(shí)調(diào)用,用于初始化非視圖相關(guān)的組件。
- onCreateView():創(chuàng)建并返回Fragment的視圖層次結(jié)構(gòu)。
- onViewCreated():視圖創(chuàng)建完成后調(diào)用,用于進(jìn)一步初始化視圖組件(對(duì)創(chuàng)建的視圖進(jìn)行進(jìn)一步初始化,如設(shè)置監(jiān)聽器、綁定數(shù)據(jù)等)。
- onStart():Fragment對(duì)用戶可見時(shí)調(diào)用。
- onResume():Fragment開始與用戶交互時(shí)調(diào)用。
- onPause():Fragment即將停止與用戶交互時(shí)調(diào)用。
- onStop():Fragment對(duì)用戶不可見時(shí)調(diào)用。
- onDestroyView():銷毀Fragment的視圖層次結(jié)構(gòu)時(shí)調(diào)用。
- onDestroy():銷毀Fragment時(shí)調(diào)用。
- onDetach():Fragment與Activity解除關(guān)聯(lián)時(shí)調(diào)用。
6.2?體驗(yàn)碎片的生命周期?
為了讓你能夠更加直觀地體驗(yàn)碎片的生命周期,我們還是通過(guò)一個(gè)例子來(lái)實(shí)踐一下。例子很簡(jiǎn)單,仍然是在FragmentTest項(xiàng)目的基礎(chǔ)上改動(dòng)的。
修改RightFragment中的代碼,如下所示
package com.example.myapplication;import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import androidx.fragment.app.Fragment;public class RightFragment extends Fragment {public static final String TAG = "RightFragment";@Overridepublic void onAttach(Context context) {super.onAttach(context);Log.d(TAG, "onAttach");}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.d(TAG, "onCreate");}public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {Log.d(TAG, "onCreateView");View view = inflater.inflate(R.layout.right_frame, container, false);return view;}public void onStart() {super.onStart();Log.d(TAG, "onStart");}@Overridepublic void onResume() {super.onResume();Log.d(TAG, "onResume");}@Overridepublic void onPause() {super.onPause();Log.d(TAG, "onPause");}@Overridepublic void onStop() {super.onStop();Log.d(TAG, "onStop");}@Overridepublic void onDestroyView() {super.onDestroyView();Log.d(TAG, "onDestroyView");}@Overridepublic void onDestroy() {super.onDestroy();Log.d(TAG, "onDestroy");}@Overridepublic void onDetach() {super.onDetach();Log.d(TAG, "onDetach");}}
我們?cè)赗ightFragment中的每一個(gè)回調(diào)方法里都加入了打印日志的代碼,然后重新運(yùn)行程序,這時(shí)觀察logcat中的打印信息。
可以看到,當(dāng)RightFragment第一次被加載到屏幕上時(shí),會(huì)依次執(zhí)行onAttach() 、onCreate() 、onCreateView() 、onActivityCreated() 、onStart() 和onResume() 方法。然后點(diǎn)擊LeftFragment中的按鈕。
????????由于AnotherRightFragment替換了RightFragment,此時(shí)的RightFragment進(jìn)入了停止?fàn)顟B(tài),因此onPause() 、onStop() 和onDestroyView() 方法會(huì)得到執(zhí)行。當(dāng)然如果在替換的時(shí)候沒有調(diào)用addToBackStack() 方法,此時(shí)的RightFragment就會(huì)進(jìn)入銷毀狀態(tài),onDestroy() 和onDetach() 方法就會(huì)得到執(zhí)行。
????????接著按下Back鍵,RightFragment會(huì)重新回到屏幕
由于RightFragment重新回到了運(yùn)行狀態(tài),因此onCreateView() 、onActivityCreated() 、onStart() 和onResume() 方法會(huì)得到執(zhí)行。注意此時(shí)onCreate() 方法并不會(huì)執(zhí)行,因?yàn)槲覀兘柚薬ddToBackStack() 方法使得RightFragment并沒有被銷毀。
?現(xiàn)在再次按下Back鍵
依次會(huì)執(zhí)行onPause() 、onStop() 、onDestroyView() 、onDestroy() 和onDetach() 方法,最終將碎片銷毀掉。這樣碎片完整的生命周期你也體驗(yàn)了一遍,是不是理解得更加深刻了?
?另外值得一提的是,在碎片中你也是可以通過(guò)onSaveInstanceState() 方法來(lái)保存數(shù)據(jù)的,因?yàn)檫M(jìn)入停止?fàn)顟B(tài)的碎片有可能在系統(tǒng)內(nèi)存不足的時(shí)候被回收。保存下來(lái)的數(shù)據(jù)在onCreate() 、onCreateView() 和onActivityCreated() 這3個(gè)方法中你都可以重新得到,它們都含有一個(gè)Bundle類型的savedInstanceState 參數(shù)。具體的代碼我就不在這里給出了,如果你忘記了該如何編寫。
參考:安卓-碎片的使用入門_android 碎片知識(shí)點(diǎn)講解-CSDN博客
?
?
?