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());