खुशबू अंदर खुशबू


137

मुझे टुकड़े के अंदर टुकड़े पर काम करने के बारे में मदद की ज़रूरत है, वास्तव में मुझे बैक बटन दबाने पर समस्या हो रही है। एप्लिकेशन मुख्य स्क्रीन में बटन होते हैं और प्रत्येक बटन पर दबाने से बटन नए टुकड़े से बदल जाता है (और उस टुकड़े में एक और टुकड़ा होता है), गतिशील रूप से जोड़ने / बदलने की जगह ठीक काम कर रहा है, बटन 1 को दबाने से टुकड़े को बदल दिया जाता है, बटन दबाने पर भी ऐसा ही होता है, लेकिन अगर बटन दबाया जाता है बटन फिर से, एक अपवाद मिला:

"Duplicate id 0x7f05000a, tag null, or parent id 0x7f050009 with
another fragment for com........ fragmentname"

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

MainActivity, जहां टुकड़े गतिशील रूप से जोड़े और बदले जाते हैं।

public class FragmentInsideFragmentTestActivity extends Activity {

    private Button button1;
    private Button button2;
    private Button button3;
    private Button button4;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        button1 =(Button) this.findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
           public void onClick(View view) {
               onButtonClick(view);
            }
        });

        button2 =(Button) this.findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                onButtonClick(view);
            }
        });

        button3 =(Button) this.findViewById(R.id.button3);
        button3.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
               onButtonClick(view);
            }
        });

        button4 =(Button) this.findViewById(R.id.button4);
        button4.setOnClickListener(new View.OnClickListener() {
           public void onClick(View view) {
               onButtonClick(view);
           }
        });
    }

    public void onButtonClick(View v) {
        Fragment fg;

        switch (v.getId()) {
           case R.id.button1:
                   fg=FirstFragment.newInstance();
                   replaceFragment(fg);
                   break;
           case R.id.button2:
                   fg=SecondFragment.newInstance();
                   replaceFragment(fg);
                   break;
           case R.id.button3:
                   fg=FirstFragment.newInstance();
                   replaceFragment(fg);
                   break;
           case R.id.button4:
                   fg=SecondFragment.newInstance();
                   replaceFragment(fg);
                   break;
        }
    }

    private void replaceFragment(Fragment newFragment) {
       FragmentTransaction trasection = getFragmentManager().beginTransaction();

        if(!newFragment.isAdded()) {
            try {
                //FragmentTransaction trasection =
                getFragmentManager().beginTransaction();
                trasection.replace(R.id.linearLayout2, newFragment);
                trasection.addToBackStack(null);
                trasection.commit();
            } catch (Exception e) {
                // TODO: handle exception
                // AppConstants.printLog(e.getMessage());
            } else {
                trasection.show(newFragment);
            }
        }
    }

यहाँ लेआउट है: main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button1" />

        <Button
            android:id="@+id/button2"
            android:text="Button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <Button
            android:id="@+id/button3"
            android:text="Button3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <Button
            android:id="@+id/button4"
            android:text="Button4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" />
</LinearLayout>

आशा है कि मैंने अपनी समस्या को दूर करने का प्रयास किया।


1
उपरोक्त कोड मेरे लिए एंड्रॉइड 3.1 के साथ पूरी तरह से ठीक काम कर रहा है
विवेक


अधिक जानकारी के लिए देखें stackoverflow.com/a/11020531/1219456
रनिज़ अहमद

जवाबों:


284

AFAIK, टुकड़े अन्य टुकड़े नहीं पकड़ सकते हैं।


अपडेट करें

एंड्रॉइड सपोर्ट पैकेज के वर्तमान संस्करणों के साथ - या एपीआई स्तर 17 और उससे अधिक पर देशी टुकड़े - आप टुकड़ों को घोंसले में डाल सकते हैं, इसके माध्यम से getChildFragmentManager()। ध्यान दें कि इसका मतलब है कि आपको एपीआई स्तरों 11-16 पर टुकड़ों के एंड्रॉइड सपोर्ट पैकेज संस्करण का उपयोग करने की आवश्यकता है, क्योंकि भले ही उन उपकरणों पर टुकड़ों का एक देशी संस्करण है, उस संस्करण में नहीं है getChildFragmentManager()


30
मंच वास्तव में यहाँ बेकार है। मैंने तीन घंटे डिबगिंग में बिताए क्योंकि आंतरिक टुकड़ा पहली बार ठीक प्रस्तुत करेगा, लेकिन स्क्रीन ओरिएंटेशन परिवर्तन के बाद गायब हो जाएगा । कोई अपवाद नहीं, लॉग जानकारी, कुछ भी नहीं। आंतरिक खंड (दया) से स्विच करना getChildFragmentManager()और निकालना setRetainInstance(true)इसे ठीक करता है। मेरे बेकन को बचाने के लिए धन्यवाद, @CommonsWare।
फेलिक्स

82

यहां छवि विवरण दर्ज करें

मुझे कुछ और संदर्भ की आवश्यकता थी, इसलिए मैंने यह दिखाने के लिए एक उदाहरण बनाया कि यह कैसे किया जाता है। तैयारी के दौरान मैंने जो सबसे उपयोगी चीज पढ़ी, वह यह थी:

गतिविधि

activity_main.xml

FrameLayoutपैरेंट टुकड़ा रखने के लिए अपनी गतिविधि में जोड़ें ।

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Activity"/>

    <FrameLayout
        android:id="@+id/parent_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="200dp"/>

 </LinearLayout>

MainActivity.java

मूल अंश को लोड करें और खंड श्रोताओं को कार्यान्वित करें। ( टुकड़ा संचार देखें )

import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity implements ParentFragment.OnFragmentInteractionListener, ChildFragment.OnFragmentInteractionListener {

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

        // Begin the transaction
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.parent_fragment_container, new ParentFragment());
        ft.commit();
    }

    @Override
    public void messageFromParentFragment(Uri uri) {
        Log.i("TAG", "received communication from parent fragment");
    }

    @Override
    public void messageFromChildFragment(Uri uri) {
        Log.i("TAG", "received communication from child fragment");
    }
}

माता-पिता का टुकड़ा

fragment_parent.xml

FrameLayoutबच्चे के टुकड़े के लिए एक और कंटेनर जोड़ें ।

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:layout_margin="20dp"
              android:background="#91d0c2">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Parent fragment"/>

    <FrameLayout
        android:id="@+id/child_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </FrameLayout>

</LinearLayout>

ParentFragment.java

उपयोग getChildFragmentManagerमें onViewCreatedबच्चे टुकड़ा स्थापित करने के लिए।

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;    

public class ParentFragment extends Fragment {

    private OnFragmentInteractionListener mListener;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_parent, container, false);
    }

    @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 onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void messageFromParentFragment(Uri uri);
    }
}

बाल भगाना

fragment_child.xml

यहां कुछ खास नहीं है।

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:layout_margin="20dp"
              android:background="#f1ff91">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Child fragment"/>
</LinearLayout>

ChildFragment.java

यहां भी कुछ खास नहीं है।

import android.support.v4.app.Fragment;

public class ChildFragment extends Fragment {

    private OnFragmentInteractionListener mListener;


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

    @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 void onDetach() {
        super.onDetach();
        mListener = null;
    }


    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void messageFromChildFragment(Uri uri);
    }
}

टिप्पणियाँ

  • सपोर्ट लाइब्रेरी का उपयोग किया जा रहा है ताकि एंड्रॉइड 4.2 से पहले नेस्टेड टुकड़े का उपयोग किया जा सके।

67

चूंकि एंड्रॉइड 4.2 (एपीआई 17) नेस्टेड टुकड़े उपलब्ध हो जाते हैं http://developer.android.com/about/versions/android-4.2.html#NestedFragments

टुकड़े को अन्य टुकड़ों के अंदर रखने के लिए getChildFragmentManager () का उपयोग करें

यह समर्थन पुस्तकालय में भी उपलब्ध है!


कृपया जवाब देने के लिए अपने उत्तर को अपडेट करें कि लिब का समर्थन पहले से ही एंड्रॉइड 1.6+ से नेस्टेड फ्रैजमेंट का समर्थन करता है
FindOutIslamNow

13

टुकड़े को अन्य टुकड़ों के अंदर जोड़ा जा सकता है, लेकिन तब आपको इसे माता-पिता के टुकड़े से हर बार निकालना होगा जब onDestroyView()माता-पिता के टुकड़े को विधि कहा जाता है। और फिर से पेरेंट फ्रैगमेंट की onCreateView()विधि में जोड़ें ।

बस इस तरह से करें:

@Override
    public void onDestroyView()
    {
                FragmentManager mFragmentMgr= getFragmentManager();
        FragmentTransaction mTransaction = mFragmentMgr.beginTransaction();
                Fragment childFragment =mFragmentMgr.findFragmentByTag("qa_fragment")
        mTransaction.remove(childFragment);
        mTransaction.commit();
        super.onDestroyView();
    }

4
इसने मेरे लिए काम नहीं किया। मेरे पास एक टुकड़ा था जिसने दो बच्चों के विचारों वाले दृश्य को फुलाया। इसमें onActivityCreated()दो टुकड़ों को जोड़ा गया है, जिसमें से प्रत्येक में एक विचार का उपयोग किया गया है getFragmentManager()। इसने पहली बार काम किया, लेकिन रोटेशन और फिर से शुरू होने पर केवल एक टुकड़ा दिखाई दे रहा था। getChildFragmentManager()इसके बजाय व्यवहार सही था । यहाँ सुझाए गए दृष्टिकोण ने एक अपवाद को फेंक दिया क्योंकि गतिविधि onSaveInstanceState()को पहले ही बुलाया जा चुका था। commitAllowingStateLoss()अपवाद का उपयोग करके लेन-देन को कम करना , लेकिन मूल समस्या को हल नहीं किया।
user1978019

8

मैंने इस समस्या को हल किया। आप समर्थन पुस्तकालय और उपयोग कर सकते हैं ViewPager। यदि आपको इशारे से स्वाइप करने की आवश्यकता नहीं है, तो आप स्वाइप को अक्षम कर सकते हैं। तो यहाँ मेरे समाधान में सुधार करने के लिए कुछ कोड है:

public class TestFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.frag, container, false);
    final ArrayList<Fragment> list = new ArrayList<Fragment>();

    list.add(new TrFrag());
    list.add(new TrFrag());
    list.add(new TrFrag());

    ViewPager pager = (ViewPager) v.findViewById(R.id.pager);
    pager.setAdapter(new FragmentPagerAdapter(getChildFragmentManager()) {
        @Override
        public Fragment getItem(int i) {
            return list.get(i);
        }

        @Override
        public int getCount() {
            return list.size();
        }
    });
    return v;
}
}

PSIt परीक्षण के लिए बदसूरत कोड है, लेकिन यह बेहतर बनाता है कि यह संभव है।

PPS इनसाइड टुकड़ा ChildFragmentManagerको पास किया जाना चाहिएViewPagerAdapter


8

आप getChildFragmentManager()फ़ंक्शन का उपयोग कर सकते हैं ।

उदाहरण:

जनक टुकड़ा:

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

    rootView = inflater.inflate(R.layout.parent_fragment, container,
            false);


    }

    //child fragment 
    FragmentManager childFragMan = getChildFragmentManager();
    FragmentTransaction childFragTrans = childFragMan.beginTransaction();
    ChildFragment fragB = new ChildFragment ();
    childFragTrans.add(R.id.FRAGMENT_PLACEHOLDER, fragB);
    childFragTrans.addToBackStack("B");
    childFragTrans.commit();        


    return rootView;
}

मूल लेआउट ( parent_fragment.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white">



    <FrameLayout
        android:id="@+id/FRAGMENT_PLACEHOLDER"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>




</LinearLayout>

बच्चे के टुकड़े:

public class ChildFragment extends Fragment implements View.OnClickListener{

    View v ;
    @Override
    public View onCreateView(LayoutInflater inflater,
                             @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View rootView = inflater.inflate(R.layout.child_fragment, container, false);


        v = rootView;


        return rootView;
    }



    @Override
    public void onClick(View view) {


    }


} 

4

यह कुछ भी जटिल नहीं है। हम getFragmentManager()यहाँ उपयोग नहीं कर सकते । एक टुकड़े के अंदर टुकड़े का उपयोग करने के लिए , हम उपयोग करते हैं getChildFragmentManager()। बाकी वही रहेगा।


3

आप FrameLayoutटुकड़े को जोड़ सकते हैं और इसे शुरू करने पर इसे दूसरे टुकड़े से बदल सकते हैं ।

इस तरह, आप दूसरे टुकड़े को पहले टुकड़े के अंदर मान सकते हैं।



2

घोंसले के टुकड़े में उत्सुकता से, नेस्टेड वन (एस) केवल समर्थित हैं यदि वे प्रोग्रामेटिक रूप से उत्पन्न होते हैं! तो इस समय कोई नेस्टेड खंड लेआउट xml लेआउट योजना में समर्थित हैं!


1

यही कारण है कि जो लोग पर काम करता है मदद मिल सकती है Kotlin आप तो एक kotlin फ़ाइल चलो का कहना है कि बनाने के विस्तार समारोह का उपयोग कर सकते "util.kt" और कोड के इस टुकड़े को जोड़ने

fun Fragment.addChildFragment(fragment: Fragment, frameId: Int) {

    val transaction = childFragmentManager.beginTransaction()
    transaction.replace(frameId, fragment).commit()
}

मान लीजिए कि यह बच्चे का वर्ग है

class InputFieldPresentation: Fragment()
{
    var views: View? = null
    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        views = inflater!!.inflate(R.layout.input_field_frag, container, false)
        return views
    }

    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        ...
    }
    ...
}

अब आप बच्चों को पिता के टुकड़े से इस तरह जोड़ सकते हैं

 FatherPresentation:Fragment()
{
  ...

    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val fieldFragment= InputFieldPresentation()
        addChildFragment(fieldFragment,R.id.fragmet_field)
    }
...
}

जहाँ R.id.fragmet_field लेआउट की आईडी है, जिसमें टुकड़ा होगा। यह गीत निश्चित रूप से पिता के टुकड़े के अंदर है। यहाँ एक उदाहरण है

पिता_ग्रेगमेंट। xml :

<LinearLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android"
    >

    ...

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:id="@+id/fragmet_field"
            android:orientation="vertical"
            >
        </LinearLayout>
    ...

    </LinearLayout>

1

MapFragmentएंड्रॉइड 3.0 के बाद से एंड्रॉइड टीम का कहना है कि इसके लिए कोई समर्थन नहीं है। यहाँ इस मुद्दे के बारे में अधिक जानकारी लेकिन आप क्या कर सकते हैं जो एक फ़्रैगमेंट बनाकर रिटर्न देता है MapActivityयहाँ एक कोड उदाहरण है। धन्यवाद इनजुक:

यह काम किस प्रकार करता है :

  • MainFragmentActivity वह गतिविधि है जो FragmentActivityदो MapFragments को विस्तारित और होस्ट करती है।
  • MyMapActivity MapActivity फैली हुई है और है MapView.
  • LocalActivityManagerFragment स्थानीयअक्टिविटीजमैन को होस्ट करता है।
  • MyMapFragment फैली हुई है LocalActivityManagerFragmentऔर MyMapActivity की TabHostआंतरिक आवृत्ति बनाने में मदद करती है।

यदि आपको कोई संदेह है तो कृपया मुझे बताएं


0

नमस्ते, मैंने इस समस्या को अलग-अलग लेआउट में डालकर हल किया है। और मैंने सिर्फ संबंधित लेआउट दिखाई दिया और दूसरों को दिखाई दिया।

मेरा मतलब:

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">

     <LinearLayout android:id="@+id/linearLayout1"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:orientation="horizontal">
           <Button android:layout_width="wrap_content"
                   android:id="@+id/button1"
                   android:layout_height="wrap_content"
                   android:text="Button1"></Button>
           <Button android:text="Button2"
                   android:id="@+id/button2"
                   android:layout_width="wrap_content"
                   android:layout_height="wrap_content"></Button>
           <Button android:text="Button3"
                   android:id="@+id/button3"
                   android:layout_width="wrap_content"
                   android:layout_height="wrap_content"></Button>
           <Button android:text="Button4"
                   android:id="@+id/button4"
                   android:layout_width="wrap_content"
                   android:layout_height="wrap_content"></Button>
   </LinearLayout>
   <LinearLayout android:layout_width="full_screen"
              android:layout_height="0dp"
              android:layout_weight="1"
              android:id="action_For_Button1"
              android:visibility="visible">
                    <Fragment android:layout_width="full_screen"
                              android:layout_height="full_screen"
                              android:id="fragment1"
                                        .
                                        .
                                        .
             / >
     </LinearLayout>

     <LinearLayout android:layout_width="full_screen"
              android:layout_height="0dp"
              android:id="action_For_Button1"
              android:layout_weight="1"
              android:visibility="gone">
                       <Fragment android:layout_width="full_screen"
                                 android:layout_height="full_screen"
                                 android:id="fragment2"
                                           .
                                           .
                                           .
             / >
        </LinearLayout>
                     .
                     .
                     .
        </LinearLayout>

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

पुनश्च: मैंने केवल यह समझने की कोशिश की कि मेरे समाधान कोड में सिंटैक्स गलतियाँ या अपूर्ण संरचना हो सकती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.