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();
}
}
}
代碼很簡單,只是引入了fragmentContentFragment
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/ ,非常感謝。