Fragment 有兩種加載方式:靜態加載和動態加載。這兩種方式加載的Fragment 與Activity 之間傳遞信息的方法是不一樣的。
使用靜態加載的Fragment 與Activity 之間的通信
如果Fragment 是使用靜態方法加載的,也就是直接在佈局文件中載入的,那麼就可以在Activity 中直接通過findViewById() 的方法獲取到Fragment 的佈局資源,例如,我在我在Fragment 的佈局中定義了一個TextView, 它的id 是frag_text,那麼我就可以在Activity 中使用下面的語句:
textView = (TextView)findViewById(R.id.frag_text);
另外。通過FragmentManager 提供的findFragmentById() 或者findFragmentByTag() 方法獲得Fragment 的實例,從而調用它的方法
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
在Fragment 中也可以通過getActivity() 來獲取當前活動的Activity 實例,例如獲取Activity 的Layout 中的View 對象:
View listView = getActivity().findViewById(R.id.list);
使用動態加載的Fragment 與Activity 之間的通信
從Activity 傳遞信息到Fragment
如果Fragment 是使用動態的方法加載的,那麼再使用findViewById() 的方法就會出現錯誤:
這裏出現了NullPointerException 的錯誤,原因就是findViewById() 的方法並沒有找到這個控件。這裏我們就要另謀它法了。
首先創建一個新的MyFragment 實例, 並調用它的setArguments() 方法:
MyFragment frag = new MyFragment();
Bundle data = new Bundle();
data.putString("text", editText.getText().toString());
frag.setArguments(data);
這裏setArguments 接收一個Bundle 型的參數
然後再用動態加載的方法替換原有的佈局:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, frag);
fragmentTransaction.commit();
然後再MyFragment 類中用getArguments() 方法接收到這個Bundle 型的數據:
Bundle bundle = getArguments();
使用內部接口實現信息的共享
上面這種方法只能實現從Activity 到Fragment 的信息傳遞,而且每傳遞一次信息,都需要新建一個Fragment,這樣顯然是比較消耗資源的。而下面使用的這種方法可以再兩個或者任意多個Fragment 和Activity 之間的數據傳遞,而且不會消耗額外的資源。
以Fragment 到Activity 之間傳遞數據爲例:
在Fragment 類中定義一個接口
public interface MyListener{
public void onFragmentDataChanged(String data);
}
在Activity 中實現這個接口並重寫其中的方法
public class MainActivity extends Activity{
...
@Override
public void onFragmentDataChanged(String data) {
textView.setText(data);
}
}
獲取實例,調用相應的回調方法
在這裏可以在Fragment 的onAttach() 方法中獲得activity 的實例,並且將它轉換成MyListener 對象:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mListener = (MyListener)activity;
}
然後就可以在合適的地方調用Activity 中重載的方法了:
mListener.onFragmentDataChanged(editText.getText().toString());