天天看点

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接收参数。