Android開(kāi)發(fā)之奇怪的Fragment

說(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。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容