2012-12-07 13 views
29

प्रोग्रामेटिक रूप से (गतिशील रूप से) Fragment एस पर getChildFragmentManager() का उपयोग कैसे करें (या "हम इसका उपयोग कर सकते हैं) getChildFragmentManager()?getChildFragmentManager() प्रोग्रामेटिक रूप से (गतिशील रूप से) जोड़ा गया टुकड़े?

यहां मेरा उदाहरण है।

मैं एक MainActivity, एक OuterFrag, और एक InnerFrag है। मैं FragmentManager द्वारा OuterFragMainActivity गतिशील रूप से जोड़ दूंगा। और, मैं InnerFragOuterFrag पर FragmentManager द्वारा गतिशील रूप से InnerFrag जोड़ दूंगा। लेकिन मैं OuterFrag के बच्चे के रूप में OuterFrag को प्रतिस्थापित नहीं करना चाहता हूं और MainActivity का नया बच्चा नहीं जोड़ना चाहता हूं।

मैं इस पदानुक्रम को रखना चाहता हूं: MainActivity -> OuterFrag -> InnerFrag। तो मुख्य गतिविधि हमेशा ऑउटरफ्रैग को कॉल कर सकती है।

लेकिन इस पदानुक्रम से बदलने के लिए: MainActivity -> OuterFrag इस पदानुक्रम के लिए: MainActivity -> InnerFrag कि MainActivity इच्छा नुकसान OuterFrag

यहां मेरा उदाहरण कोड है।

MainActivity.java

package com.example.frag; 

import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 

public class MainActivity extends FragmentActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, new OuterFrag()).commit(); 
     getSupportFragmentManager().executePendingTransactions(); 

     System.out.println("Before: " 
       + getSupportFragmentManager().findFragmentById(R.id.frameLayout)); 

     ((OuterFrag) getSupportFragmentManager().findFragmentById(R.id.frameLayout)) 
       .addInnerFrag(); 

     System.out.println("After: " 
       + getSupportFragmentManager().findFragmentById(R.id.frameLayout)); 
    } 
} 

activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/frameLayout" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 
</FrameLayout> 

OuterFrag.java

package com.example.frag; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

public class OuterFrag extends Fragment { 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.outer_frag, container, false); 
    } 

    public void addInnerFrag() { 

     getFragmentManager().beginTransaction().replace(this.getId(), new InnerFrag()).commit(); 
     getFragmentManager().executePendingTransactions(); 

//  getChildFragmentManager().beginTransaction().add(this.getId(), new InnerFrag()).commit(); 
//  getChildFragmentManager().executePendingTransactions(); 
    } 
} 

outer_frag.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/textView1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="i am the OUTER frag" /> 

InnerFrag.java

package com.example.frag; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

public class InnerFrag extends Fragment { 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.inner_frag, container, false); 
    } 
} 

inner_frag.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/textView2" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="i am the INNER frag" /> 

वर्तमान में, इसके बाद के संस्करण कोड त्रुटियों के बिना चला सकते हैं। लेकिन यह वास्तव में InnerFrag को MainActivity के नए बच्चे के रूप में बदल रहा है। यह दो सिस्टम प्रिंट आउट कथन द्वारा सत्यापित किया जा सकता है कि पहले: ऑब्जेक्ट और बाद: ऑब्जेक्ट बदल गया है। का उपयोग करते हुए getChildFragmentManager() सैद्धांतिक रूप से सही है

12-07 02:29:38.406: E/AndroidRuntime(12051): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.frag/com.example.frag.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f070000 (com.example.frag:id/frameLayout) for fragment InnerFrag{46e32748 #0 id=0x7f070000} 

: OuterFrag.java में, getChildFragmentManager() बयान getFragmentManager() बयानों के बजाय चलाए जा रहे हैं, तो हम निम्न रनटाइम त्रुटि मिल जाएगा। इसका उपयोग गैर-प्रोग्रामेटिक रूप से जोड़े गए खंड में किया जा सकता है (जिसका अर्थ है activity_main.xml के <FrameLayout> से <fragment>, विशेषता android:name="com.example.frag.OuterFrag" जोड़ें, और MainActivity.java में पहले getSupportFragmentManager() कथन को हटाएं)।और यह सही पदानुक्रम रख रहा है: MainActivity -> OuterFrag -> InnerFrag। लेकिन मूल खंड (outer_frag.xml) के शब्दों को कभी नहीं हटाया जा सकता है।

अंत में, मैं MainActivity में OuterFrag संदर्भ के लिए हमेशा चाहता हूँ। और मुझे OuterFrag अलग-अलग InnerFrag एस लोड करने के लिए प्लेसहोल्डर के रूप में कार्य करना है। संक्षेप में, मैं को OuterFrag पर कॉल करना चाहता हूं, जब इसे प्रोग्रामेटिक रूप से (गतिशील रूप से) जोड़ा जाता है।

+0

आप इस काम के मिली थी? मेरा सवाल यह है कि जब आप 'इनरफ्रैग' जोड़ते हैं तो यह 'ऑउटरफ्रैग' के जीवन चक्र के साथ सहजता से फिट बैठता है? – StuStirling

उत्तर

45

In conclusion, I want to reference OuterFrag in MainActivity always. And I want OuterFrag act as a placeholder to load different InnerFrags. In short, I want to call getChildFragmentManager() in OuterFrag, when it is added programmatically (dynamically).

आप इस चाहते हैं, तो आपके OuterFrag अपनी सामग्री के रूप में एक कंटेनर लेआउट बनाने के लिए और है कि कंटेनर के लिए जो कुछ भी InnerFrag जोड़ें। OuterFrag के लिए लेआउट फ़ाइल हो जाएगा:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/fragContainer" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
/> 
बेशक

आप OuterFrag के लिए लेआउट में अन्य विचार हो सकता था अगर आपको लगता है कि चाहते हैं। फिर अपने addInnerFrag विधि हो जाएगा:

public void addInnerFrag() { 
     getChildFragmentManager().beginTransaction().add(R.id.fragContainer, new InnerFrag()).commit(); 
     getChildFragmentManager().executePendingTransactions(); 
} 

मुख्य गतिविधि के लिए OuterFrag जोड़ने के लिए कोड मान्य रहता है।

+1

यह पूरी तरह से काम करता है! आपका बहुत बहुत धन्यवाद! – midnite

+0

हाय @ लक्सप्रोग मैंने उपर्युक्त विधि का पालन किया है और इनर फ्रैगमेंट को बाहरी फ्रैगमेंट में जोड़ा गया है। लेकिन बाहरी फ्रेगमेंट सामग्री को प्रतिस्थापित नहीं कर रहा है। इसे एक दृश्य के रूप में जोड़ा गया है और बाहरी फ्रेगमेंट में पिछली सामग्री भी दिखाई दे रही है। मैंने ** startTransaction() का उपयोग करने का भी प्रयास किया है। ** को प्रतिस्थापित करें लेकिन ऑप में कोई बदलाव नहीं है। कृपया मेरी मदद करें ................... –

+1

@ KK_07k11A0585 कृपया अपनी समस्या के बारे में अधिक जानकारी प्रदान करने वाला एक नया प्रश्न पोस्ट करें। ध्यान रखें कि एक टुकड़ा लेनदेन उन विचारों को प्रतिस्थापित नहीं करेगा जो पहले से ही लेआउट में हैं जहां टुकड़ा जोड़ा जाएगा। यदि आप इसे भी बदलना चाहते हैं तो उन प्रारंभिक विचारों को किसी अन्य खंड में रखें। – Luksprog

0

आप अपने OuterFrag.java कोड के भीतर addInnerFrag() कॉल करना चाहते हैं, तो आप इसे इस तरह कर सकते हैं:

OuterFrag.java:

@Override 
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 
    addInnerFrag(); 
}