अभिविन्यास परिवर्तन पर फ्रैगमेंट को संभालने के लिए मूर्ख-प्रूफ तरीका


87
public class MainActivity extends Activity implements MainMenuFragment.OnMainMenuItemSelectedListener {

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

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager
            .beginTransaction();

    // add menu fragment
    MainMenuFragment myFragment = new MainMenuFragment();
    fragmentTransaction.add(R.id.menu_fragment, myFragment);

    //add content
    DetailPart1 content1= new DetailPart1 ();
    fragmentTransaction.add(R.id.content_fragment, content1);
    fragmentTransaction.commit();

}
public void onMainMenuSelected(String tag) {
  //next menu is selected replace existing fragment
}

मुझे दो सूची दृश्य साथ-साथ, बाईं ओर मेनू और दाईं ओर इसकी सामग्री प्रदर्शित करने की आवश्यकता है। डिफ़ॉल्ट रूप से, पहला मेनू चुना जाता है और इसकी सामग्री दाईं ओर प्रदर्शित होती है। सामग्री को प्रदर्शित करने वाला टुकड़ा निम्नानुसार है:

public class DetailPart1 extends Fragment {
  ArrayList<HashMap<String, String>> myList = new ArrayList<HashMap<String, String>>();
  ListAdapter adap;
  ListView listview;

  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
      super.onActivityCreated(savedInstanceState);

       if(savedInstanceState!=null){
        myList = (ArrayList)savedInstanceState.getSerializable("MYLIST_obj");
        adap = new LoadImageFromArrayListAdapter(getActivity(),myList );
        listview.setAdapter(adap);
       }else{
        //get list and load in list view
        getlistTask = new GetALLListTasks().execute();
    }


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


     @Override
      public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
          outState.putSerializable("MYLIST_obj", myList );
        }
    }

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


आमतौर पर टुकड़ों के उन्मुखीकरण में बदलाव का ध्यान रखे बिना आपको कुछ भी करने की आवश्यकता होती है। जब आप अभिविन्यास बदलते हैं, तो आपको क्या समस्या है?
अलेक्जेंडर कुलाख़्तिन

एलेक्स मैं वर्ग ModePart1 टुकड़ा की जरूरत है चित्र मोड में listView के साथ लेआउट प्रदर्शित करने के लिए और ग्रिड परिदृश्य के साथ लेआउट में परिदृश्य मोड। इस के लिए, मैं हर बार टुकड़ा फिर से बनाने की जरूरत है, लेकिन मैं फिर से एक ही रिकॉर्ड लोड नहीं करना चाहता, इसलिए मैं उन्हें onSaveInstanceState पर संग्रहीत करें। लेकिन उपरोक्त कोड दो बार डिटेलपार्ट 1 को फिर से बनाता है, मुझे लापता कोड को जानना होगा जो इसे वांछित बनाता है
user1811741

जवाबों:


132

जब भी आप अपनी गतिविधि में स्क्रीन को चालू करते हैं तो आप एक नया टुकड़ा बना रहे हैं, onCreate();लेकिन आप पुराने को भी बनाए रख रहे हैं super.onCreate(savedInstanceState);। तो हो सकता है कि टैग लगा दें और अगर यह मौजूद है, या सुपर के लिए अशक्त बंडल पास टुकड़े को ढूंढें।

मुझे सीखने में थोड़ा समय लगा और यह वास्तव में एक द्वि **** हो सकता है जब आप व्यूपेजर जैसे सामान के साथ काम कर रहे हों।

मैं आपको टुकड़ों के बारे में एक अतिरिक्त समय पढ़ने की सलाह दूंगा क्योंकि यह सटीक विषय कवर किया गया है।

यहाँ एक उदाहरण है कि नियमित अभिविन्यास परिवर्तन पर टुकड़ों को कैसे संभालना है:

गतिविधि :

public class MainActivity extends FragmentActivity {

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

        if (savedInstanceState == null) {
            TestFragment test = new TestFragment();
            test.setArguments(getIntent().getExtras());
            getSupportFragmentManager().beginTransaction().replace(android.R.id.content, test, "your_fragment_tag").commit();
        } else {
            TestFragment test = (TestFragment) getSupportFragmentManager().findFragmentByTag("your_fragment_tag");
        }
    }
}

टुकड़ा :

public class TestFragment extends Fragment {

    public static final String KEY_ITEM = "unique_key";
    public static final String KEY_INDEX = "index_key";
    private String mTime;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_layout, container, false);

        if (savedInstanceState != null) {
            // Restore last state
            mTime = savedInstanceState.getString("time_key");
        } else {
            mTime = "" + Calendar.getInstance().getTimeInMillis();
        }

        TextView title = (TextView) view.findViewById(R.id.fragment_test);
        title.setText(mTime);

        return view;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("time_key", mTime);
    }
}

आपके प्रयास के लिए धन्यवाद Warpzit, लेकिन अगर आप अपने बिंदु के बारे में कोड में समझाते हैं तो मुझे खुशी होगी। खंड को फिर से लोड किए बिना अभिविन्यास परिवर्तन को संभालने के लिए मेरे कोड को बदलने के लिए कैसे।
user1811741

1
इसलिए मुझे अभिविन्यास पर बदले जाने वाले टुकड़े के लेआउट की आवश्यकता है, लेकिन मैं सभी रिकॉर्डों को फिर से लोड नहीं करना चाहता, मैंने जो किया वह था 1. 1. एंड्रॉइड को जोड़ें: घोषणापत्र = "अभिविन्यास" प्रकट में 2. ओवरराइड onConfigurationChanged टुकड़ा में बदल दिया और उन्मुखीकरण का पता लगाने और अभिविन्यास के आधार पर लिस्टव्यू या ग्रिडव्यू छिपाना / दिखाना यह सही तरीका है?
user1811741

@ user1811741 उदाहरण के साथ अपडेट किया गया। मुझे उम्मीद है कि यह सब कुछ स्पष्ट कर देगा।
वारपज़िट

@Warpzit ViewPager फ़्रैगमेंट कार्यान्वयन के मामले में उसी परिदृश्य को कैसे संभाला जा सकता है क्योंकि ViewPager सभी प्रदर्शित टुकड़े का ध्यान रखता है..जो सुझाव।
कोडे डे

1
@ अच्छी तरह से मेरा मानना ​​है कि व्यूपेंजर इसे ठीक से हैंडल करता है, अगर नहीं तो आपको अपनी आवश्यकताओं को पूरा करने के लिए getItem कार्यान्वयन को ओवरराइड करना होगा। आशा है कि आप सही दिशा में इशारा किया है, अगर एक उचित सवाल नहीं किया :)
Warpzit

21

अभिविन्यास परिवर्तन और गतिविधि मनोरंजन के बीच डेटा को कैसे बनाए रखा जाए, इसके बारे में एक अच्छी दिशानिर्देश Android दिशानिर्देशों में पाया जा सकता है ।

सारांश:

  1. अपना टुकड़ा बनाए रखने योग्य:

    setRetainInstance(true);
    
  2. आवश्यक होने पर ही एक नया टुकड़ा बनाएँ (या उससे कम से कम डेटा लें)

    dataFragment = (DataFragment) fm.findFragmentByTag("data");
    
    // create the fragment and data the first time
    if (dataFragment == null) {
    

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