天天看點

Fragment之間消息傳遞

Google官方文檔上說:為了讓fragments更子產品化,Fragments之間不要進行直接的互動,可以使用接口的方法。 

In order to reuse the Fragment UI components, you should build each as a completely self-contained, modular component that defines its own layout and behavior. Once you have defined these reusable Fragments, you can associate them with an Activity and connect them with the application logic to realize the overall composite UI.

Often you will want one Fragment to communicate with another, for example to change the content based on a user event. All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.

本人親測了一下,源碼在github上:點這裡點這裡點這裡。

首先定義一個fragment: ServerFragment.java,在裡面定義一個接口:

package com.example.zach.fragtofragcommunicationdemo;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
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.EditText;

/**
 * Created by Zach on 8/15/2017.
 */

public class ServerFragment extends Fragment {
    OnFragmentSelectedListener mCallback;
    Button button;
    EditText editText;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.server, container, false);
        button = (Button) view.findViewById(R.id.btn);
        editText = (EditText) view.findViewById(R.id.info);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mCallback.onFragmentSelected(editText.getText().toString());
            }
        });
        return view;
    }

    public interface OnFragmentSelectedListener {
        public void onFragmentSelected(String info);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
            mCallback = (OnFragmentSelectedListener)context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString() + "Mush implement OnFragmentSelectedListener ");
        }
    }
}
           

然後在MainActivity中實作這個接口,也就是說如果某一個事件發生,需要傳遞這個消息到另一個fragment中,這段代碼寫在接口的具體實作中。

package com.example.zach.fragtofragcommunicationdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements ServerFragment.OnFragmentSelectedListener{
    ServerFragment serverFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getSupportFragmentManager().beginTransaction().addToBackStack(null).replace(R.id.container, new ServerFragment()).commit();

    }

    @Override
    public void onFragmentSelected(String info) {
        ClientFragment clientFragment  = new ClientFragment();
        Bundle args = new Bundle();
        args.putString("info", info);
        clientFragment.setArguments(args);
        getSupportFragmentManager().beginTransaction().addToBackStack(null).replace(R.id.container, clientFragment).commit();

    }
}
           

最後就是消息接收方的fragment,用bundle接收參數,直接處理一下:

package com.example.zach.fragtofragcommunicationdemo;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Created by Zach on 8/16/2017.
 */

public class ClientFragment extends Fragment {
    TextView textView;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.client, container, false);
        textView = (TextView) view.findViewById(R.id.infoFromFrag);
        Bundle args = new Bundle();
        args = getArguments();

       textView.setText(args.getString("info") + "");
        return view;
    }
}
           

總的來講,如果要實作fragments之間消息的傳遞,步驟如下:

  1. 在發送消息的fragment中定義一個接口;
  2. 在hosting activity中實作這個接口,并用bundle把消息傳送給另一個fragment
  3. 在接收消息的fragment中定義bundle接收參數。