问题描述
当活动和片段中都有startActivityForResult
时, 返回时到底会调用哪个的onActivityResult
?
分析
我们知道, 尽管我们可以直接在片段中调用startActivityForResult
, 但是它背后的逻辑还是交由活动来处理的. 换句话说, 不管你在哪里调用startActivityForResult
, 活动中的onActivityResult
是以一定会被回调的.
除此以外, 在片段中, 你既可以直接调用startActivityForResult
, 也可以通过getActivity().startActivityForResult
的方式启动. 如果采取后者, 那么回调逻辑就需要完全放在活动代码中处理了.
到这里, 问题的解决就出现了两种思路:
1.回调逻辑全部放在活动中处理, 再有活动通知相对应的片段进行业务操作.
2.回调逻辑分别放在活动与片段中各自处理
操作
- 在活动中统一处理
这种思路基本上有两种操作方法: 通知和回调.
你可以使用广播或eventBus来进行通知
public class ActivityResultEvent {
private int requestCode;
private int resultCode;
private Intent data;
public ActivityResultEvent(int requestCode, int resultCode, Intent data) {
this.requestCode = requestCode;
this.resultCode = resultCode;
this.data = data;
}
public int getRequestCode() {
return requestCode;
}
public void setRequestCode(int requestCode) {
this.requestCode = requestCode;
}
public int getResultCode() {
return resultCode;
}
public void setResultCode(int resultCode) {
this.resultCode = resultCode;
}
public Intent getData() {
return data;
}
public void setData(Intent data) {
this.data = data;
}
}
public class ActivityResultBus extends Bus {
private static ActivityResultBus instance;
public static ActivityResultBus getInstance() {
if (instance == null)
instance = new ActivityResultBus();
return instance;
}
private Handler mHandler = new Handler(Looper.getMainLooper());
public void postQueue(final Object obj) {
mHandler.post(new Runnable() {
@Override
public void run() {
ActivityResultBus.getInstance().post(obj);
}
});
}
}
public class MainActivity extends ActionBarActivity {
...
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
ActivityResultBus.getInstance().postQueue(
new ActivityResultEvent(requestCode, resultCode, data));
}
...
}
public class BodyFragment extends Fragment {
...
@Override
public void onStart() {
super.onStart();
ActivityResultBus.getInstance().register(mActivityResultSubscriber);
}
@Override
public void onStop() {
super.onStop();
ActivityResultBus.getInstance().unregister(mActivityResultSubscriber);
}
private Object mActivityResultSubscriber = new Object() {
@Subscribe
public void onActivityResultReceived(ActivityResultEvent event) {
int requestCode = event.getRequestCode();
int resultCode = event.getResultCode();
Intent data = event.getData();
onActivityResult(requestCode, resultCode, data);
}
};
...
}
public class BodyFragment extends Fragment {
...
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Don't forget to check requestCode before continuing your job
if (requestCode == 12345) {
// Do your job
tvResult.setText("Result Code = " + resultCode);
}
}
...
}
当然, 简洁点就用回调
//1.自定义接口作为回调方法
public interface OnFragmentResultListener {
public void OnFragmentResult(int requestCode,int resultCode,Intent data);
}
//2.在Activity里处理回调
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//得到fragment
Fragment fragment=getSupportFragmentManager().findFragmentById(R.id.fragment_container);
/**
* 判断是不是Activity里面Fragment的回调,如果是传递给Fragment
*/
if(fragment instanceof OnFragmentResultListener){
OnFragmentResultListener listener=(OnFragmentResultListener) fragment;
listener.OnFragmentResult(requestCode, resultCode, data);
}
super.onActivityResult(requestCode, resultCode, data);
}
//3.Fragment实现OnFragmentResultListener 接口重写OnFragmentResult方法,作为回调
- 各自为政
这种情况下, 不管是在活动还是片段中调用startActivityForResult
, 只会回调活动中的onActivityResult
, 要想同时调用片段中的回调方法, 则需在活动中的回调方法中加入super.onActivityResult(requestCode, resultCode, data);
, 这样两者都会被回调.