說(shuō)起Android中的Fragment,在使用的時(shí)候稍加注意,就會(huì)發(fā)現(xiàn)存在以下兩種:
- v4包中的兼容Fragment,android.support.v4.app.Fragment
- 普通的Fragment,android.app.Fragment
這兩種Fragment在使用過(guò)程中千萬(wàn)不要來(lái)回串,否則會(huì)出現(xiàn)莫名其妙的錯(cuò)誤
</br>
一、不同版本的使用規(guī)則
1、3.0以上:xml中可以直接引用<fragment>,這個(gè)是android.app.Fragment,在host Activity中可以使用getFragmentManager()來(lái)獲取FragmentManager;
-
2、3.0以下:
- 首先libs目錄必須有android-support-v4.jar,能用Fragment全靠它了。
- 使用的Activity必須繼承自FragmentActivity,使用getSupportFragmentManager獲取FragmentManager;雖然名字一樣但是與高版本導(dǎo)入的包名不一樣。
- 不使用布局文件的<fragment />標(biāo)簽,使用其他layout作為容器,然后在程序動(dòng)態(tài)生成。
注意: 這兩個(gè)方法都是為了得到FragmentManager,名字一樣但是包名不一樣。
</br>
二、使用Fragment
- 繼承Fragment類(lèi)來(lái)寫(xiě)一個(gè)Fragment,創(chuàng)建和定義如下:
public class Fragment1 extends Fragment { ... }
- Fragment只能存在于Activity中,所以必須要在某處定義它,有兩種方式:
- 直接在xml布局文件中定義;
- 在xml布局文件中定義一個(gè)占位符,然后動(dòng)態(tài)地在Activity中操作Fragment。
注意: Fragment的定義方式會(huì)影響它的生命周期,因?yàn)樵诘谝环N情況下onInflate方法會(huì)被調(diào)用,而第二種情況下它的生命周期是從onAttach方法開(kāi)始的。
</br>
- 1、如果在XML文件中定義Fragment的話,需要:
<fragment android:id="@+id/fragment"
class="com.yungfan.fragment.Fragment1"
android:layout_width="match_parent"
android:layout_height="20dp"/>
- 2、如果在XML中用占位符的話,就不能自由、動(dòng)態(tài)修改Fragment了,此時(shí)需要在XML文件中定義:
<FrameLayout android:id="@+id/fl"
android:layout_width="match_parent"
android:layout_height="200dp"/>
然后在Activity里面手動(dòng)初始化Fragment,然后把它 “插入”到FrameLayout中。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Fragment2 f2 = new Fragment2();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fl, f2);
ft.commit();
}
三、Activity獲取Fragment
//3.0以下用 getSupportFragmentManager
FragmentManager fm = getFragmentManager();
//找到對(duì)應(yīng)的fragment
Fragment1 f1 = (Fragment1)fm.findFragmentById(R.id.fragment1);
四、Fragment相互通信
可以在Fragment1中通過(guò)
FragmentManager fm = getActivity().getFragmentManager();
Fragment2 f2 = fm.findFragmentById(R.id.fragment2);
獲取Fragment2,然后可以調(diào)用Fragment2中的方法
注意:兩個(gè)單獨(dú)的Fragment之間是不應(yīng)該進(jìn)行通信的,應(yīng)該使用host Activity來(lái)進(jìn)行通信。官方推薦做法是:先Fragment1跟它的Activity通信,可以在Fragment1類(lèi)中定義一個(gè)接口,并在Activity中實(shí)現(xiàn)該接口,然后在Activity中與Fragment2通信。
</br>
五、Fragment中獲取Activity上下文為null的情況
有時(shí)候在Fragment調(diào)用getActivity返回為null,此時(shí)可以在Fragment的構(gòu)造方法中,傳遞一個(gè)參數(shù)Activity。然后在Activity中new Fragment時(shí)將自己傳遞過(guò)去即可。
六、Fragment不響應(yīng)onActivityResult
問(wèn)題描述:在Fragment中使用startActivityForResult起了一個(gè)activity,activity運(yùn)行完返回結(jié)果時(shí),F(xiàn)ragement的onActivityResult卻不會(huì)被調(diào)用。override了host fragment的FragmentActivity的onActivityResult,發(fā)現(xiàn)onActivityResult在這里可以被調(diào)用到。
原因及解決辦法:返回的result先傳至Fragment的host Activity。這個(gè)host Activity的onActivityResult函數(shù)必須調(diào)用super.onActiivtyResult()。super.onActiivtyResult會(huì)將未被處理的result消息繼續(xù)傳給其host的fragement的onActiivtyResult。