Android 为Fragment 和Activity之间的通信提供了两种机制:
机制1:
①Fragment获取它所在的Activity
调用Fragment的getActivity()方法即可返回它所在的Activity实例,之后我们就能够通过这个实例调用findViewById(int) 方法了,也就是说,我们能够在Fragment中得到相关联的Activity的组件的信息 ,如:
TextView textView = (TextView)getActivity().findViewById(R.id.textView) ;
之后就能够获得TextView中的字符内容
②Activity 获取它绑定的Fragment
调用Activity关联的FragmentManager的findFragmentById(int id) 或者findViewByTag(String tag)方法,即可获得指定的Fragment对象,获得这个Fragment对象之后,我们就能够调用中这个对象的getView()方法,这个方法返回的是OnCreate()方法中返回的那个View , 也就是Fragment的布局View,这样就能够操作Fragment中的组件了
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
View view = fragment.getView() ;
TextView textView = (TextView)findViewById(R.id.textView);
③引申
我们想既然通过①②的方法能够返回Activity和Fragment实例对象,那么我们就能够在Fragment和Activity之间进行实时的通信,
我们想如果我们如下的一个Activity子类 ;
public class MainActivity extends Activity { public void show(String text ) { .......具体的操作......... } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
................................................ } }
如果这个Activity 中添加了一个Fragment对象的话,那么我们就能够在这个Fragment类中的某个方法中使用下面的的代码:
((MainActivity)getActivity()).show("you are right") ;//注意使用强制类型转换,要不不行
也就是说,我们能够在Fragment中直接调用Activity中的方法,这就非常的有用了,你想如果Fragment中的某个信息想要实时的传给Activity,那么就可以在这个信息需要传递的时候将这个信息作为参数调用Activity中的方法,将这个信息传给Activity ; 同理由于Activity能够返回Fragment,那么也就能够调用Fragment中的任意的方法,实现Activity到Fragment的实时通信
④Fragment和Fragment之间的通信
由于一个Activity之中能够同时加载多个Fragment,那么就会存在Fragment和Fragment之间的通信问题
既然Fragment和Activity之间的通信问题解决了,那Fragment与Fragment之间的通信也没有那么复杂。基本思路是:
首先在一个Fragment中可以得到与它相关联的Activity,然后再通过这个Activity去获取另外一个Fragment的实例,这样就实现了不同Fragment之间的通信。
机制2 :
①Activity向Fragment中传递数据
在Activity中创建Bundle数据包,并调用Fragment对象的setArguments(Bundle bundle)方法
(也就是说我们得要首先创建一个Fragment对象之后才能够用这个对象调用setArgument(Bundle)方法)即可将Bundle数据包传递给该Fragment对象;之后在Fragment类中调用getArguments()方法就能够获得这个Bundle包
这个方法一般用在Activity加载一个Fragment的时候,由于当我们加载一个Fragment的时候就想要将一些数据传给Fragment对象,来对Fragment对象进行初始化,所以在Fragment中的onCreate()或者onCreateView()方法中调用getArgument()方法来获得这个Bundle对象,
②Fragment实时的向Activity通信
实际就是使用接口回调的机制,也就是在Fragment中定义一个内部回调接口,再让包含该Fragment的Activity类实现这个接口,这样Fragment就能够调用这个回调方法,将数据传给Activity中
public class MyFragment extends Fragment { private Callbacks mCallbacks; // 定义一个回调接口,该Fragment所在Activity需要实现该接口 // 该Fragment将通过该接口与它所在的Activity交互 public interface Callbacks {
//回调方法 public void onItemSelected(参数); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
} // 当该Fragment被添加、显示到Activity时,回调该方法 @Override public void onAttach(Activity activity) { super.onAttach(activity); // 如果Activity没有实现Callbacks接口,抛出异常 if (!(activity instanceof Callbacks)) { throw new IllegalStateException( "Fragment所在的Activity必须实现Callbacks接口!"); } // 把该Activity当成Callbacks对象 mCallbacks = (Callbacks)activity; } // 当该Fragment从它所属的Activity中被删除时回调该方法 @Override public void onDetach() { super.onDetach(); // 将mCallbacks赋为null。 mCallbacks = null; }
@Override
public View OnCreateView()
{
....................
}
.......一定的时机...........
//调用回调方法
mCallbacks.onItemSelected(数据); }
public class MyActivity extends Activity implements MyFragment.Callbacks { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_book_twopane); } // 实现Callbacks接口必须实现的方法 @Override public void onItemSelected(参数 data) { data中就是Fragment传来的数据
} }
不同的Activity可以同时实现这个Fragment中的接口和接口中的方法,但是实现方式可以不同,这样的话,我们就能够在多个Activity之间重用这个Fragment的时候,却有不同的Activity效果了
