Android的Fragment中onActivityResult不被调用的终极解决方案

Fragment中的onActivityResult不被调用,有几种情况,请大家一一排查。

 

1.检查该Fragment所属的Activity中,是否重写了onActivityResult方法。

如果是该种情况,请确保写了super.onActivityResult:

Java代码   收藏代码
  1. @Override  
  2. protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  3.     super.onActivityResult(requestCode, resultCode, data);  
  4.     if (resultCode == RESULT_OK) {  
  5.         //Activity中相关处理代码  
  6.     }  
  7. }  

 

2.检查Fragment中的startActivityForResult的调用方式。

请确保不要使用getActivity().startActivityForResult方法,而是要直接使用startActivityForResult。

 

3.如果以上两方面都没能解决问题,很可能是如下情况了,略有复杂:

该情况是在support library中使用了Nested Fragment,就是说在Fragment中进行了嵌套,比如用ViewPager展示Fragment等情况。这可以算Google的一个Bug,具体可参见这篇博客:

http://blog.shamanland.com/2014/01/nested-fragments-for-result.html

解决方案:

最好的方式是写一个BaseActivity继承FragmentActivity,重写onActivityResult方法,你用到的Activity都继承BaseActivity来做。BaseActivity具体实现:

 

Java代码   收藏代码
  1. package com.jupaidaren.android;  
  2.   
  3. import java.util.List;  
  4.   
  5. import android.content.Intent;  
  6. import android.support.v4.app.Fragment;  
  7. import android.support.v4.app.FragmentActivity;  
  8. import android.support.v4.app.FragmentManager;  
  9. import android.util.Log;  
  10.   
  11. abstract public class BaseActivity extends FragmentActivity {  
  12.   
  13.     private static final String TAG = "BaseActivity";  
  14.   
  15.     @Override  
  16.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  17.         FragmentManager fm = getSupportFragmentManager();  
  18.         int index = requestCode >> 16;  
  19.         if (index != 0) {  
  20.             index--;  
  21.             if (fm.getFragments() == null || index < 0  
  22.                     || index >= fm.getFragments().size()) {  
  23.                 Log.w(TAG, "Activity result fragment index out of range: 0x"  
  24.                         + Integer.toHexString(requestCode));  
  25.                 return;  
  26.             }  
  27.             Fragment frag = fm.getFragments().get(index);  
  28.             if (frag == null) {  
  29.                 Log.w(TAG, "Activity result no fragment exists for index: 0x"  
  30.                         + Integer.toHexString(requestCode));  
  31.             } else {  
  32.                 handleResult(frag, requestCode, resultCode, data);  
  33.             }  
  34.             return;  
  35.         }  
  36.   
  37.     }  
  38.   
  39.     /** 
  40.      * 递归调用,对所有子Fragement生效 
  41.      *  
  42.      * @param frag 
  43.      * @param requestCode 
  44.      * @param resultCode 
  45.      * @param data 
  46.      */  
  47.     private void handleResult(Fragment frag, int requestCode, int resultCode,  
  48.             Intent data) {  
  49.         frag.onActivityResult(requestCode & 0xffff, resultCode, data);  
  50.         List<Fragment> frags = frag.getChildFragmentManager().getFragments();  
  51.         if (frags != null) {  
  52.             for (Fragment f : frags) {  
  53.                 if (f != null)  
  54.                     handleResult(f, requestCode, resultCode, data);  
  55.             }  
  56.         }  
  57.     }  
  58. }  

 


//----------------------------------------------------------------------------------------------------------------------------------------

public class MainActivity extends FragmentActivity {
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_fragment);

		FragmentManager fragmentManager = getSupportFragmentManager(); 
		FragmentTransaction ft = fragmentManager.beginTransaction();
		ft.add(R.id.content, new FragmentTest());
		ft.commit();
	}
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		//super.onActivityResult(requestCode, resultCode, data);
		
		if (resultCode != Activity.RESULT_OK) {
			return;
		}

		String result = data.getStringExtra("data");
		Toast.makeText(this, result+ "2222222222222222", Toast.LENGTH_SHORT).show();
	}
}


public class FragmentTest extends Fragment implements OnClickListener{
	private static final int REQUEST_CODE_SECOND = 0x11;
	Button btn;
	@Override
	public View onCreateView(LayoutInflater inflater,
			@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.fragment_layout, container, false);
		
		btn = (Button) view.findViewById(R.id.btn);
		btn.setOnClickListener(this);
		return view;
	}
	
	@Override
	public void onClick(View v) {
		Intent intent  = new Intent(getActivity(), SecondActivity.class);
		startActivityForResult(intent, REQUEST_CODE_SECOND);
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		
		if (resultCode != Activity.RESULT_OK) {
			return;
		}
		
		if (requestCode == REQUEST_CODE_SECOND) {
			String result = data.getStringExtra("data");
			Toast.makeText(getActivity(), result, Toast.LENGTH_SHORT).show();
		}
	}
}


public class SecondActivity extends FragmentActivity  implements OnClickListener{
	Button btn;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_second);
		btn = (Button) findViewById(R.id.btn);
		
		btn.setOnClickListener(this);
	}
	
	@Override
	public void onClick(View v) {
		Intent intent = new Intent();
		intent.putExtra("data", "coding");
		setResult(Activity.RESULT_OK, intent);
		finish();
	}
}


(1)结果这里仅仅弹出了coding2222222222222222,并没有弹出coding。

需要将MainActivity中调用super.onActivityResult(requestCode, resultCode, data);。


(2)在MainActivity中调用super.onActivityResult(requestCode, resultCode, data);,

然后弹出的效果,是先弹出coding,然后在弹出coding2222222222222222。

可以推测一下执行的相关顺序。








  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值