0

我在使用FragmentPagerAdapter時遇到了一些問題,無法正確地分割片段之間的通信。在改變方向後無法正確地與分段進行通信

對於某些上下文,我有一個活動使用FragmentPagerAdapter來託管兩個片段。片段A有一個按鈕,當它按下時它改變了片段B中的文本。

一切都按預期工作,除非在方向更改後按下按鈕時,我在EditText上得到空指針異常,我在片段B中更改。經過幾天的調試,看起來像我調用Fragment B中的方法,改變了它可能是Fragment的舊實例的文本。

下面的代碼:

的FragmentPagerAdapter這是在我的活動的內部類:

public class MyPagerAdapter extends FragmentPagerAdapter { 

    public MyPagerAdapter (FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int i) { 
     switch (i) { 
      case 0: 
       return fragmentA; 
      case 1: 
       return fragmentB; 
     } 
     return null; 
    } 

    @Override 
    public int getCount() { 
     return tabs.length; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     return tabs[position]; 
    } 
} 

碎片得到了活動onCreate方法實例如下:

FragmentA fragmentA; //Declared outside of onCreate 
FragmentB fragmentB; //Declared outside of onCreate 

fragmentA = FragmentA.newInstance(); 
fragmentB = FragmentB.newInstance(); 

在我按下按鈕的片段我設置了一個界面如下:

@Override 
public void onAttach(Activity activity) { 
    super.onAttach(activity); 
    try { 
     testTextInterface = (TestTextInterface) activity; 
    } catch (ClassCastException e) { 
     throw new ClassCastException(activity.toString() 
       + " must implement testTextInterface"); 
    } 
} 

然後當我按下按鈕,我有閃光下面的代碼的OnClickListener:

testTextInterface.onTextChanged("Some test text"); 

進而調用活動中的下列方法:

@Override 
public void onTextChanged(String testText) { 
    fragmentB.updateText(testText); 

} 

然後終於說在片段B中的方法:

private void updateText(String incomingText){ 
    myEditText.setText(incomingText); 
} 

而就是這樣,這個工作非常好直到我旋轉設備導致活動被重新創建。然後,當我按下按鈕時,myEditText視圖在updateText方法中的FragmentB中爲null。

我一直在試圖弄清楚爲什麼2天,所以我想知道如果任何人都可以發現我要去哪裏錯或指向我在正確的方向,我可能會介意什麼是導致問題?

+0

你是如何的片段連接到活動?在oncreate?如果是這樣,當你旋轉設備onCreate將被調用一個非空的包。因此,您應該檢查'savedInstanceState'是否爲空,然後僅附加碎片。此外,我會擺脫onAttach回調以及您保留在活動片段中的引用。相反,當您需要在活動中調用監聽器時,只需在片段中執行'getActivity()'。 – 2014-11-20 22:57:04

+0

還有一件事,在適配器中,你是否將實例保存到碎片中,而不是創建新的碎片?如果是這樣,檢查[這個答案](http://stackoverflow.com/questions/6976027/reusing-fragments-in-a-fragmentpageradapter)。 – 2014-11-20 22:59:41

+0

我沒有手動附加片段自己,我相信FragmentPagerAdapter自動在getItem方法中做到這一點? – 2014-11-21 01:23:25

回答

1

問題是,當你旋轉的時候,Android會爲你創建你的片段的新實例,但是你沒有獲得對這些新實例的引用。不要在活動中保留對片段的引用,而是在需要時使用findFragmentByTag。

@Override 
public void onTextChanged(String testText) { 
    Fragment fragmentB = getFragmentManager().findFragmentByTag("FragmentB"); 
    fragmentB.updateText(testText); 
} 

而且,當然,確保在XML或代碼中設置片段的標記。

+0

事情是我不認爲我可以使用這與FragmentPAgerAdapter作爲碎片沒有ID? – 2014-11-21 01:18:20

+1

如果您只有每種類型片段的一個實例,那麼您只需在調用newInstance之後立即設置一個ID或標記。這樣你就知道每一個FragmentA或FragmentB的實例都會有你分配給它的標籤或ID。 Android將在旋轉後重新創建片段後維護片段標籤和ID。 – Bruce 2014-11-21 01:21:42

1

我同意李小龍,但如果你需要保持在活動中的片段的引用,你可以做這樣的事情:

在你的活動,實施的方法,讓我們說「setFragmentInstance」。

在片段中,重寫onActivityCreated方法,您可以在其中將活動轉換爲活動(如果片段始終保留在該活動中)並調用setFragmentInstance方法,或者也可以在片段中添加接口,實現它的活動並在onActivityCreated中調用接口的方法來設置片段實例。

我問過一個類似的問題,但不久之後,我得到了明確一下,看DialogFragment members becomes null after screen rotation

相關問題