टिप्पणियों में राहुल शर्मा की सलाह के बाद, मैंने चाइल्ड फ्रैगमेंट से माता-पिता के टुकड़े और गतिविधि में संवाद करने के लिए इंटरफ़ेस कॉलबैक का उपयोग किया। मैं भी submitted this answer to Code Review। मैं वहां एक गैर-उत्तर ले रहा हूं (इस लेखन के समय) यह संकेत है कि इस डिजाइन पैटर्न के साथ कोई बड़ी समस्या नहीं है। ऐसा लगता है कि मुझे आधिकारिक fragment communication docs में दिए गए सामान्य मार्गदर्शन के अनुरूप होना चाहिए।
उदाहरण परियोजना
निम्न उदाहरण परियोजना उदाहरण प्रश्न में दिए गए विस्तृत करता है। इसमें ऐसे बटन हैं जो टुकड़ों से गतिविधि तक और बाल टुकड़े से माता-पिता के टुकड़े तक ऊपर संचार शुरू करते हैं।
मैं इस तरह परियोजना लेआउट सेट:
मुख्य गतिविधि
गतिविधि दोनों टुकड़े से श्रोताओं को लागू करता है, ताकि वह उन लोगों से संदेश प्राप्त कर सकते हैं।
वैकल्पिक TODO: यदि गतिविधि टुकड़ों के साथ संचार शुरू करना चाहता था, तो यह केवल उनके लिए प्रत्यक्ष संदर्भ प्राप्त कर सकता था और फिर उनकी सार्वजनिक विधियों में से एक को कॉल कर सकता था।
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity implements ParentFragment.OnFragmentInteractionListener, ChildFragment.OnChildFragmentToActivityInteractionListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.parent_fragment_container, new ParentFragment());
ft.commit();
}
@Override
public void messageFromParentFragmentToActivity(String myString) {
Log.i("TAG", myString);
}
@Override
public void messageFromChildFragmentToActivity(String myString) {
Log.i("TAG", myString);
}
}
जनक टुकड़ा
जनक टुकड़ा बाल टुकड़ा से श्रोता को लागू करता है, ताकि वह यह से संदेश प्राप्त कर सकते हैं।
वैकल्पिक TODO: यदि अभिभावक टुकड़ा बाल टुकड़े के साथ संचार शुरू करना चाहता था, तो यह केवल इसका प्रत्यक्ष संदर्भ प्राप्त कर सकता था और फिर अपने सार्वजनिक तरीकों में से एक को कॉल कर सकता था।
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ParentFragment extends Fragment implements View.OnClickListener, ChildFragment.OnChildFragmentInteractionListener {
// **************** start interesting part ************************
private OnFragmentInteractionListener mListener;
@Override
public void onClick(View v) {
mListener.messageFromParentFragmentToActivity("I am the parent fragment.");
}
@Override
public void messageFromChildToParent(String myString) {
Log.i("TAG", myString);
}
public interface OnFragmentInteractionListener {
void messageFromParentFragmentToActivity(String myString);
}
// **************** end interesting part ************************
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_parent, container, false);
view.findViewById(R.id.parent_fragment_button).setOnClickListener(this);
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
Fragment childFragment = new ChildFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.child_fragment_container, childFragment).commit();
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
बाल टुकड़ा
बाल टुकड़ा दोनों गतिविधि के लिए और माता पिता के लिए टुकड़ा श्रोता इंटरफेस को परिभाषित करता है। यदि चाइल्ड फ्रैगमेंट को केवल उनमें से एक के साथ संवाद करने की आवश्यकता है, तो अन्य इंटरफ़ेस को हटाया जा सकता है।
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ChildFragment extends Fragment implements View.OnClickListener {
// **************** start interesting part ************************
private OnChildFragmentToActivityInteractionListener mActivityListener;
private OnChildFragmentInteractionListener mParentListener;
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.child_fragment_contact_activity_button:
mActivityListener.messageFromChildFragmentToActivity("Hello, Activity. I am the child fragment.");
break;
case R.id.child_fragment_contact_parent_button:
mParentListener.messageFromChildToParent("Hello, parent. I am your child.");
break;
}
}
public interface OnChildFragmentToActivityInteractionListener {
void messageFromChildFragmentToActivity(String myString);
}
public interface OnChildFragmentInteractionListener {
void messageFromChildToParent(String myString);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
// check if Activity implements listener
if (context instanceof OnChildFragmentToActivityInteractionListener) {
mActivityListener = (OnChildFragmentToActivityInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnChildFragmentToActivityInteractionListener");
}
// check if parent Fragment implements listener
if (getParentFragment() instanceof OnChildFragmentInteractionListener) {
mParentListener = (OnChildFragmentInteractionListener) getParentFragment();
} else {
throw new RuntimeException("The parent fragment must implement OnChildFragmentInteractionListener");
}
}
// **************** end interesting part ************************
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_child, container, false);
view.findViewById(R.id.child_fragment_contact_activity_button).setOnClickListener(this);
view.findViewById(R.id.child_fragment_contact_parent_button).setOnClickListener(this);
return view;
}
@Override
public void onDetach() {
super.onDetach();
mActivityListener = null;
mParentListener = null;
}
}
आपको पेरेंटफ्रैगमेंट इंस्टेंस विधि –
बनाना होगा, आप अपने ऐप में ** कॉलबैक ** का उपयोग कर ऐसा कर सकते हैं। –
आपके पास इवेंटबस जैसे [ओटो] (http://square.github.io/otto/) या [ग्रीनरोबोट] (https://github.com/greenrobot/EventBus) –