两个具有接口的片段之间的通信

Communication between two fragments with interface

我的应用程序有一个 activity A 和两个片段 F1 和 F2。

点击F1中的按钮,F1被F2取代。 我想将F1中的数据传输到F2。为此,我在 F1 中实现了接口并在 A 中覆盖了它的方法。

但是当从A发送数据到F2时,我对F2的引用(sFragment in code A)仍然为空,由于数据不会发送到 F2。我正在使用 F2 替换 F1 时提供的 TAG 引用 F2。

它是否与生命周期有关,例如当我试图获取对尚未创建的 F2 的引用时?

F1

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){

    View v = inflater.inflate(R.layout.form_fragment1,container,false); 
    nextB = (Button) v.findViewById(R.id.f1Next);
    nextB.setOnClickListener(this);
    return v;
}

@Override
public void onClick(View view) {
    switch (view.getId()){

        case R.id.f1Next:
            SFragment fragment = new SFragment();
            FragmentManager mManager = getFragmentManager();
            FragmentTransaction mTransaction = mManager.beginTransaction();
            mTransaction.replace(R.id.fragment_container,fragment,"SecondF"); // SecondF
            mTransaction.addToBackStack(null);  // this is required to move to the previous fragment
            mTransaction.commit();
            commListener.PlaceName(data1,data2);  //passing value to activity
            break;

    }

}
interface CommBridge{

    void PlaceName(String data1,String data2);
}

@Override
public void onAttach(Context context){
    super.onAttach(context);
    if (context instanceof CommBridge){
        commListener= (CommBridge) context;
    }
}

}

一个

 @Override
public void PlaceName(String data1, String data2) {
    SFragment sFragment=(SFragment) getFragmentManager().findFragmentByTag("SecondF");
    if (sFragment != null && sFragment.isInLayout()){
        Log.d("STATE","1");
        sFragment.setPlace(data1,data2);
    }else{
        Log.d("STATE","2");  // this is always  the case
    }

F2

public class SFragment extends Fragment {
String Place2,Place1;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
    View v = inflater.inflate(R.layout.form_fragment2,container,false);
    return v;
}

void setPlace(String data1, String data2){
    place1 = data1;
    place2 =  data2;

}
}

我建议将替换片段的代码放在 Activity 中,并将应该传递给 SFragment() 的值直接放在其参数中:

SFragment newFragment = new SFragment();
Bundle args = new Bundle();
args.putString("place1", data1);
args.putString("place2", data1);
newFragment.setArguments(args);

你可以在 SFragment#onCreateView()

得到它们
String place1 = getArguments().getString("place1");

也可以看看这里:https://developer.android.com/training/basics/fragments/communicating.html

让activity负责处理Fragment的onClick事件。请参见下面的示例。

Activity:

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

public class MainActivity extends AppCompatActivity implements Fragment1.CommBridge {


    private Fragment1 fragment1 = new Fragment1();
    private Fragment2 fragment2 = new Fragment2();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.content, fragment1)
                .commit();


    }

    @Override
    public void onButtonClicked(String data1, String data2) {
        fragment2.setData(data1, data2);
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.content, fragment2)
                .commit();
    }
}

片段 1:

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;

public class Fragment1 extends Fragment {

    interface CommBridge {
        void onButtonClicked(String data1, String data2);
    }

    private CommBridge handler;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof CommBridge) {
            handler = (CommBridge) context;
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment1, container, false);

        Button button = (Button) view.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                handler.onButtonClicked("Data1", "Data2");
            }
        });

        return view;
    }
}

片段2

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;

public class Fragment2 extends Fragment {

    private String data1;
    private String data2;

    public void setData(String data1, String data2) {
        this.data1 = data1;
        this.data2 = data2;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment2, container, false);

        TextView textView = (TextView) view.findViewById(R.id.textView);
        textView.setText(data1 + "\n" + data2);

        return view;
    }
}