(9)Fragment間的數據傳遞

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/ ,非常感謝。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章