1.分析
有一种比较特殊的情况,就是两个Fragment在同一个Activity中:例如,点击当前Fragment中按钮,弹出一个对话框(DialogFragment),在对话框中的操作需要返回给触发的Fragment中,那么如何数据传递呢?
记住我们在一个Activity中,那么肯定不是使用startActivityForResult;但是我们返回的数据,依然在onActivityResult中进行接收。
使用官方推荐的弹窗:
2.解决方案
使用dialog.setTargetFragment(ContentFragment.this, REQUEST_EVALUATE);,通过设置目标Fragment,然后通过手动调用onActivityForResult方法
3.一个小例子
MainActivity
package com.xzy.fragmentbasicdemo; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import com.xzy.fragmentbasicdemo.fragment.ContentFragment; /** * 测试fragment的一些用法: * 1.fragment之间传参 */ public class MainActivity extends FragmentActivity { private ContentFragment mContentFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentManager fm = getSupportFragmentManager(); /** * 在activity_main的根布局添加ID属性,值为id_fragment_container * */ mContentFragment = (ContentFragment) fm.findFragmentById(R.id.id_fragment_container); if (mContentFragment == null) { mContentFragment = new ContentFragment(); fm.beginTransaction().replace(R.id.id_fragment_container, mContentFragment).commit(); } } }代码很简单,只是引入了fragment
ContentFragment
package com.xzy.fragmentbasicdemo.fragment; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.Toast; import com.xzy.fragmentbasicdemo.R; import static android.app.Activity.RESULT_OK; import static com.xzy.fragmentbasicdemo.fragment.EvaluateDialog.RESPONSE_EVALUATE; /** * A simple {@link Fragment} subclass. */ public class ContentFragment extends Fragment { private static final String TAG = "ContentFragment"; public static final int REQUEST_EVALUATE = 0x12; public static final String EVALUATE_DIALOG = "evaluate_dialog"; public ContentFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_content, container, false); Button button = view.findViewById(R.id.btn_test); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { EvaluateDialog dialog = new EvaluateDialog(); //注意setTargetFragment dialog.setTargetFragment(ContentFragment.this, REQUEST_EVALUATE); dialog.show(getFragmentManager(), EVALUATE_DIALOG); } }); return view; } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_EVALUATE) { if (resultCode != RESULT_OK) { return; } if (data != null) { /** * 取参 * */ String param = data.getStringExtra(RESPONSE_EVALUATE); Toast.makeText(getActivity(), param, Toast.LENGTH_SHORT).show(); } //do something } } }在Fragment中我们给button添加了点击事件,点击后即初始化弹窗,并调用了:
dialog.setTargetFragment(ContentFragment.this, REQUEST_EVALUATE)
我们调用了Fragment.setTargetFragment ,这个方法,一般就是用于当前fragment由别的fragment启动,在完成操作后返回数据的,符合我们的需求,这句很重要。
下面是弹窗类的代码
package com.xzy.fragmentbasicdemo.fragment; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.DialogFragment; /** * 官方推荐的使用DialogFragment创建对话框 */ public class EvaluateDialog extends DialogFragment { private String[] mEvaluteVals = new String[]{"GOOD", "BAD", "NORMAL"}; public static final String RESPONSE_EVALUATE = "response_evaluate"; @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle("Evaluate :").setItems(mEvaluteVals, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { setResult(which); } }); return builder.create(); } // 设置返回数据 protected void setResult(int which) { // 判断是否设置了targetFragment if (getTargetFragment() == null) return; Intent intent = new Intent(); intent.putExtra(RESPONSE_EVALUATE, mEvaluteVals[which]); //手动调用onActivityResult getTargetFragment().onActivityResult(ContentFragment.REQUEST_EVALUATE, Activity.RESULT_OK, intent); } }
重点就是看点击后的setResult了,我们首先判断是否设置了targetFragment,如果设置了,意味我们要返回一些数据到targetFragment。
我们创建intent封装好需要传递数据,最后手动调用onActivityResult进行返回数据~~
最后我们在ContentFragment的onActivityResult接收即可。
是不是很6!
4.参考文章
- 部分参考了http://blog.csdn.net/lmj623565791/article/details/42628537/ ,非常感谢。