2013-07-03 11 views
9

मेरे पास Activity एकाधिक Fragment एस के साथ है। मैं DialogFragment दिखाना चाहता हूं या Fragment में से किसी एक से Fragment खोलना चाहता हूं। मुझे पता है कि Activity को Fragment एस खोलने के साथ काम किया जाना चाहिए, इसलिए मैंने कुछ चीजों की कोशिश की है।गतिविधि और टुकड़ा इंटरैक्शन

पहले
मैं getActivity() उपयोग करें और यह डाली तो मैं एक Fragment दिखाने के लिए Activity में एक विधि कॉल कर सकते हैं लेकिन यह Activity साथ Fragment में एक निर्भरता बनाता है और मैं चाहते हैं निर्भरता को जोड़ने से बचने के लिए करने की कोशिश की अगर संभव हो तो।

दूसरा
अगला मैं Activity है कि यह एक Fragment दिखाना चाहिए सूचित करने के लिए एक श्रोता की कोशिश की। तो मैंने श्रोता इंटरफेस को लागू करने के लिए Activity में एक कक्षा बनाई। लेकिन मुझे समस्याएं थीं क्योंकि मुझे New MyActivity().new Listener(); का उपयोग करना था और को फेंकने पर का उपयोग करने की कोशिश की गई थी क्योंकि के इस उदाहरण को प्रारंभ नहीं किया गया था।

तृतीय
मैं तो करने के लिए Activity सीधे श्रोता को लागू जो काम करता है क्योंकि तब मैं केवल श्रोता और नहीं गतिविधि के साथ एक निर्भरता बनाने हूँ की कोशिश की। हालांकि अब मैं उस बिंदु पर जा रहा हूं जहां मेरा Activity 2 - 4 अलग-अलग इंटरफेस लागू करेगा जो मुझे संकोच कर रहा है क्योंकि इससे गंभीरता कम हो जाएगी।

तो किसी भी तरह से मैंने कोशिश की है कि मैं एक ईंट की दीवार में दौड़ रहा हूं और निर्भरता पैदा कर रहा हूं, मुझे यकीन नहीं है कि मुझे बनाने की ज़रूरत है। क्या मैं खराब हूं और इन विकल्पों में से किसी एक के साथ जाना है? यदि ऐसा है तो कौन सा विकल्प सबसे अच्छा होगा? किसी भी मदद या सुझावों की बहुत सराहना की जाती है।

+0

ऐसा करने के कई तरीके हैं, मैं चीजों को यथासंभव डी-युग्मित पसंद करता हूं, और इसके लिए मुझे एक ईवेंट बस पसंद है। उदाहरण के लिए देखें: http://square.github.io/otto/। (आपको सभी इंटरफ़ेस/श्रोता क्रूर से छुटकारा मिल जाता है। डेटा पास करें, इसे मजबूत प्रकार के साथ करें, इसे स्पष्ट संक्षेप में करें।) –

+0

ऐसा लगता है कि यह आशाजनक है। मुझे इसे देखना होगा। पारितोषिक के लिए धन्यवाद। –

उत्तर

10

व्यक्तिगत रूप से मैं कहूंगा कि टुकड़ों को पुन: प्रयोज्य और मॉड्यूलर घटकों के रूप में सोचा जाना चाहिए। तो यह पुनः उपयोगिता प्रदान करने के लिए, टुकड़ों को अपनी मूल गतिविधियों के बारे में ज्यादा नहीं पता होना चाहिए। लेकिन बदले में गतिविधियों को उनके टुकड़ों के बारे में पता होना चाहिए।

तो, पहला विकल्प कभी भी निर्भरता कारण के लिए मेरी राय में नहीं माना जाना चाहिए जिसका आपने बहुत अधिक युग्मित कोड उत्पन्न किया है।

दूसरे विकल्प के बारे में, टुकड़े किसी भी आवेदन प्रवाह या यूआई से संबंधित निर्णयों का प्रतिनिधित्व कर सकते हैं (एक नया टुकड़ा दिखा रहा है, यह निर्णय लेना कि एक टुकड़ा विशिष्ट घटना ट्रिगर आदि कब करना है)। तो आपके श्रोताओं/कॉलबैक को टुकड़ा विशिष्ट होना चाहिए और इस प्रकार उन्हें टुकड़ों में घोषित किया जाना चाहिए। और इन टुकड़ों को रखने वाली गतिविधियों को इन इंटरफेस को लागू करना चाहिए और यह तय करना चाहिए कि क्या करना है।

तो मेरे लिए तीसरा विकल्प अधिक समझ में आता है। मेरा मानना ​​है कि वे जो कुछ भी पकड़ रहे हैं और विशिष्ट कॉलबैक पर कर रहे हैं, उनके संदर्भ में गतिविधियां अधिक पठनीय हैं। लेकिन हाँ आप सही हैं कि आपकी गतिविधि एक ईश्वर वस्तु बन सकती है।

शायद आप कई इंटरफेस को लागू नहीं करना चाहते हैं तो आप स्क्वायर Otto प्रोजेक्ट की जांच कर सकते हैं। यह मूल रूप से एक घटना बस है।

FragmentTransaction ft = 
    getActivity().getSupportFragmentManager().beginTransaction(); 
Fragment prev = 
    getActivity().getSupportFragmentManager().findFragmentByTag("some_name"); 
if (prev != null) { 
    ft.remove(prev); 
} 
ft.addToBackStack(null); 

DialogFragment dialogFragment = DialogFragmentClass.newInstance(); 
dialogFragment.show(ft, "some_name"); 

मुझे जानते हैं, चियर्स:

+0

ओटो लाइब्रेरी को इंगित करने के लिए आपको और @ चार्ली कॉलिन्स के लिए धन्यवाद। ऐसा लगता है कि यह बहुत ही आशाजनक लगता है और ऐसा लगता है कि मैं जो कुछ भी ढूंढ रहा हूं उसे पूरा कर लेगा। मदद करने के लिए सभी को धन्यवाद। –

3

मुझे लगता है कि आपका दूसरा विकल्प सही रास्ते पर है।

अपने टुकड़ा में, परिभाषित श्रोता इंटरफ़ेस:

class MyFragment ... 
{ 
    public interface IMyFragmentListenerInterface 
    { 
     void DoSomething(); 
    } 
} 

गतिविधि इंटरफ़ेस को लागू है:

class MyActivity 
{ 
    class MyListener1 implements IMyFragmentListenerInterface { ... } 
} 

टुकड़ा करने के लिए श्रोता दर्रा। मैं इसे फ्रैगमेंट के कन्स्ट्रक्टर में करना पसंद करता हूं, लेकिन यह केवल तभी काम करता है जब आप अपने टुकड़ों को पूरी तरह से प्रबंधित करते हैं। आप इसके बजाय अपने टुकड़े में setListener विधि जोड़ सकते हैं।

+3

'सेट लिस्टनर' दृष्टिकोण में कोई समस्या है: यदि फ्रैगमेंट नष्ट हो गया है और ओएस द्वारा पुन: बनाया गया है (डिफ़ॉल्ट रिक्त कन्स्ट्रक्टर का उपयोग करके), श्रोता का संदर्भ खो जाएगा। इसे प्राप्त करने का सबसे अच्छा तरीका है कि टुकड़े की मूल गतिविधि को श्रोता होने के लिए 'ऑन अटैच' विधि में कोड डालना, रनटाइम पर जांच करना जो आवश्यक इंटरफ़ेस का समर्थन करता है। Http://developer.android.com/guide/components/fragments.html देखें: 'गतिविधि में ईवेंट कॉलबैक बनाना'। –

0

आप कुछ इस तरह (टुकड़ा से) कोशिश की है।

2

आपको अपने डेटा को फ्रैगमेंट एक्स से अपनी फ्रैगमेंट एक्टिविटी तक पास करने की आवश्यकता होगी जो इस डेटा को आपके फ्रैगमेंट वाई पर पास कर देगा। आप अपने खंड वर्ग में परिभाषित इंटरफ़ेस के माध्यम से ऐसा करते हैं और उस कॉलबैक को तुरंत चालू करते हैं जिसे परिभाषित किया गया है onAttach()। यह कैसे यहाँ Communication With other Fragments

त्वरित उदाहरण क्या करने पर

अधिक जानकारी, पर विचार टुकड़ा एक और टुकड़ा बी टुकड़ा एक एक सूची टुकड़ा है और जब भी एक आइटम का चयन किया गया है कि यह क्या टुकड़ा बी में प्रदर्शित किया जाता बदल जाएगा काफी सरल, सही?

पहले, इस तरह फ्रैगमेंट ए को परिभाषित करें।

public class FragmentA extends ListFragment{ 

    //onCreateView blah blah blah 

} 

और यहाँ टुकड़ा बी

public class FragmentB extends Fragment{ 

//onCreateView blah blah blah 

} 

है और यहाँ मेरी FragmentActivity है कि उन्हें नियंत्रित करेंगे दोनों

public class MainActivity extends FragmentActivity{ 

//onCreate 
//set up your fragments 

} 

मुमकिन है आप पहले से ही कुछ इस तरह है, अब यहाँ आप कैसे बदलेगा FragmentA (सूची खंड जो हमें कुछ डेटा प्राप्त करने की आवश्यकता है)।

public class FragmentA extends ListFragment implements onListItemSelectedListener, onItemClickListener{ 

OnListItemSelectedListener mListener; 

    //onCreateView blah blah blah 



// Container Activity must implement this interface 
    public interface OnListItemSelectedListener { 
    public void onListItemSelected(int position); 
} 


} 


    @Override 
    public void onAttach(Activity activity) { 
    super.onAttach(activity); 

    // This makes sure that the container activity has implemented 
    // the callback interface. If not, it throws an exception 
    try { 
     mListener = (OnListItemSelectedListener) activity; 
    } catch (ClassCastException e) { 
     throw new ClassCastException(activity.toString() 
       + " must implement OnListItemSelectedListener"); 
    } 
} 


    @Override 
public void onItemClick(AdapterView<?> parent, View view, int position, long id){ 


//Here's where you would get the position of the item selected in the list, and pass that position(and whatever other data you need to) up to the activity 
//by way of the interface you defined in onAttach 

    mListener.onListItemSelected(position); 


} 

सबसे महत्वपूर्ण विचार यह है कि आपकी मूल गतिविधि इस इंटरफ़ेस को लागू करती है, अन्यथा आपको अपवाद मिलेगा। यदि सफलतापूर्वक कार्यान्वित किया जाता है, तो हर बार आपकी सूची खंड में कोई आइटम चुना जाता है, आपकी गतिविधि को इसकी स्थिति के बारे में अधिसूचित किया जाएगा। जाहिर है आप किसी भी संख्या या पैरामीटर के साथ अपने इंटरफ़ेस को बदल सकते हैं, इस उदाहरण में हम बस हमारे पूर्णांक स्थिति में गुजर रहे हैं। उम्मीद है कि यह एक छोटे से आदमी, शुभकामनाएं स्पष्ट करता है।

0

अधिकतम ढीले युग्मन प्राप्त करने के लिए आप ग्रीनरोबोट से स्क्वायर या इवेंटबस से ओटीटीओ जैसी घटना बस का उपयोग कर सकते हैं। आपके टुकड़े ऐसी घटनाओं को आग लगा सकते हैं जो आपकी गतिविधि द्वारा संभाले जाते हैं और इसके विपरीत। इसके बारे में अच्छी बात यह है कि घटकों (गतिविधियों, टुकड़े) एक दूसरे के बारे में कुछ भी नहीं है और आपको किसी भी इंटरफेस या कॉलबैक घोषित करने की आवश्यकता नहीं है।

मैं इसे अपनी सभी परियोजनाओं में उपयोग करता हूं और यह मजबूत है और प्रदर्शन (सामान्य परिस्थितियों में) पर कोई प्रभाव नहीं पड़ता है।

2

इंटरफ़ेस बनाएँ

public interface ListenFromActivity { 
    void doSomethingInFragment(); 
} 

में गतिविधि वर्ग

public ListenFromActivity activityListener; 

स्थापित करने के लिए श्रोता

public void setActivityListener(ListenFromActivity activityListener) { 
     this.activityListener = activityListener; 
    } 

गतिविधि कक्षा में कुछ ट्रिगर बिंदु जोड़े सार्वजनिक विधि बनाएं ListenFromActivity इंटरफ़ेस का refrence रखने , एच पहले मैं टुकड़ा वर्ग

में उपयोगकर्ता बातचीत का इस्तेमाल किया है

@Override 
    public void onUserInteraction() { 
     super.onUserInteraction(); 

     if (null != activityListener) { 
      activityListener.doSomethingInFragment(); 
     } 
    } 

अब आप अपने टुकड़ा लागू इंटरफ़ेस वर्ग बनाने

public class SomeFragment extends Fragment implements ListenFromActivity 

एंड्रॉयड स्टूडियो टुकड़ा

में इंटरफ़ेस के विधि को लागू करने के लिए संकेत देगा
void doSomethingInFragment() 
{//Add your code here 
} 

अंतिम हिस्सा हिस्सा श्रोता टुकड़ा में इस तरह की गतिविधि के लिए उदाहरण onCreate विधि

((ListnerActivity) getActivity()).setActivityListener(SomeFragment.this); 

हो गया !!। अब आप गतिविधि से खंड विधि को कॉल कर सकते हैं।

संबंधित मुद्दे