两个片段之间的通信与接口

时间:2017-07-20 13:51:39

标签: android android-fragments android-lifecycle fragment-lifecycle

我的应用有一个活动A和两个片段F1和F2。

F1中的一个点击按钮,F1被F2替换。 我想将F1中的数据传输到F2。为此,我在F1中实现了接口,并在A。

中覆盖了它的方法

但是当从A发送数据到F2时,我对F2的引用( 代码A 中的sFragment)仍然为空,因为哪些数据没有发送到F2 。我正在使用提供的TAG参考F2,同时用F2替换F1。

它是否与生命周期有关,就像我试图引用它尚未创建的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;
    }
}

}

A

 @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;

}
}

2 个答案:

答案 0 :(得分:2)

让活动负责处理Fragment的onClick事件。请参阅下面的示例。

<强>活动:

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;
    }
}

<强> Fragment2

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;
    }
}

答案 1 :(得分:0)

我建议将代码替换为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