2012-09-19 43 views
48

मेरे पास कस्टम ऑब्जेक्ट्स के साथ ArrayList है जो मैं स्क्रीन को घुमाने और सहेजने में सक्षम होना चाहता हूं।एंड्रॉइड स्क्रीन पर कस्टम ऐरेलिस्ट को कैसे सहेजना है?

मैं जानता हूँ कि इस onSaveInstanceState और onRestoreInstanceState साथ किया जा सकता है कि अगर मैं ArrayList अपने ही वर्ग है, जो लागू करता है या तो Parcelable या Serializable ... लेकिन वहाँ एक और वर्ग बनाने के बिना यह करने के लिए एक तरीका है बनाने के लिए कर रहे थे?

उत्तर

81

आपको अपनी कस्टम ऑब्जेक्ट्स के ऐरेलिस्ट को पास करने के लिए एक नई कक्षा बनाने की आवश्यकता नहीं है। आपको बस अपनी ऑब्जेक्ट के लिए पार्सेलबल क्लास को कार्यान्वित करना चाहिए और Bundle#putParcelableArrayList()onSaveInstanceState() और onRestoreInstanceState() में उपयोग करना चाहिए। यह विधि पार्ससेल के एक ऐरेलिस्ट को स्वयं ही संग्रहित करेगी।


क्योंकि Parcelables (और Serializables और बंडल) का विषय कभी कभी मेरे सिर में चोट लगी है, यहाँ एक ArrayList एक बंडल में संग्रहीत कस्टम Parcelable वस्तुओं से युक्त की एक बुनियादी उदाहरण है। (यह, & पेस्ट runnable कटौती नहीं लेआउट आवश्यक है।)

कार्यान्वयन Parcelable

public class MyObject implements Parcelable { 
    String color; 
    String number; 

    public MyObject(String number, String color) { 
     this.color = color; 
     this.number = number; 
    } 

    private MyObject(Parcel in) { 
     color = in.readString(); 
     number = in.readString(); 
    } 

    public int describeContents() { 
     return 0; 
    } 

    @Override 
    public String toString() { 
     return number + ": " + color; 
    } 

    public void writeToParcel(Parcel out, int flags) { 
     out.writeString(color); 
     out.writeString(number); 
    } 

    public static final Parcelable.Creator<MyObject> CREATOR = new Parcelable.Creator<MyObject>() { 
     public MyObject createFromParcel(Parcel in) { 
      return new MyObject(in); 
     } 

     public MyObject[] newArray(int size) { 
      return new MyObject[size]; 
     } 
    }; 
} 

आप onRetainNonConfigurationInstance() उपयोग कर सकते हैं सहेजें/पुनर्स्थापित स्टेट्स

public class Example extends ListActivity { 
    ArrayList<MyObject> list; 

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

     if(savedInstanceState == null || !savedInstanceState.containsKey("key")) { 
      String[] colors = {"black", "red", "orange", "cyan", "green", "yellow", "blue", "purple", "magenta", "white"}; 
      String[] numbers = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"}; 

      list = new ArrayList<MyObject>(); 
      for(int i = 0; i < numbers.length; i++) 
       list.add(new MyObject(numbers[i], colors[i])); 
     } 
     else { 
      list = savedInstanceState.getParcelableArrayList("key"); 
     } 

     setListAdapter(new ArrayAdapter<MyObject>(this, android.R.layout.simple_list_item_1, list)); 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     outState.putParcelableArrayList("key", list); 
     super.onSaveInstanceState(outState); 
    } 
} 
+1

धन्यवाद! हालांकि, मैं 'निजी MyObject (पार्सल इन) { रंग = in.readString() पर खो गया हूं; संख्या = in.readString(); } 'बिट ... स्ट्रिंग्स के लिए यह आसान है, लेकिन मैं अपनी कस्टम सरणीसूची कैसे पढ़ूं? 'in.readArrayList (MyObject.class.getClassLoader()) 'मुझे एक त्रुटि देता है। – Kalina

+1

हम्म, आपके प्रश्न में आपने "कस्टम ऑब्जेक्ट्स के साथ एक ऐरेलिस्ट" के बारे में पूछा, जिसका अर्थ है 'ऐरेलिस्ट ', जो यह उत्तर 'पार्ससेल योग्य' निर्माता 'में हैडल करता है; हालांकि आपकी टिप्पणी ने अभी पूछा है कि "MyArrayList' का अर्थ" मैं अपनी कस्टम सरणी सूची कैसे पढ़ूं "। आप किस वर्ग का विस्तार करने की कोशिश कर रहे हैं? (तकनीकी होने के लिए खेद है, लेकिन मैं आपको सबसे अच्छा जवाब देना चाहता हूं।) – Sam

+0

क्षमा करें, मेरा मतलब है ऐरेलिस्ट Kalina

3

। यह आपको कॉन्फ़िगरेशन परिवर्तन से पहले किसी ऑब्जेक्ट को सहेजने की अनुमति देता है, और getLastNonConfigurationInstanceState() के साथ इसे पुनर्स्थापित करता है।

गतिविधि के अंदर

:

@Override 
    public Object onRetainNonConfigurationInstance() { 
     return myArrayList; 
    } 

onCreate() के अंदर:

try{ 
     ArrayList myArrayList = (ArrayList)getLastNonConfigurationInstance(); 
    } catch(NullPointerException e) {} 

हैंडलिंग क्रम परिवर्तन: http://developer.android.com/guide/topics/resources/runtime-changes.html प्रलेखन: http://developer.android.com/reference/android/app/Activity.html#onRetainNonConfigurationInstance%28%29

+0

वाह, उस समारोह के बारे में कभी नहीं पता था! सुपर सरल और बिल्कुल मुझे जो चाहिए ... हालांकि, मुझे लगता है कि यह बहिष्कृत है ... – Kalina

+0

दुर्भाग्य से, लेकिन यह अभी भी काम करता है और ऐसा करने का कोई और आसान तरीका नहीं है। सैम का जवाब मुझे मिला एकमात्र अन्य तरीका है, लेकिन इसे लागू करना बहुत कठिन है। – Techwolf

+3

यदि आप फ्रैगमेंट्स का उपयोग कर रहे हैं, तो आप इसके बजाय 'Fragment.setRetainInstance (true)' का उपयोग कर सकते हैं, जो इसका नया संस्करण है (लेकिन केवल Fragments के साथ काम करता है)। प्रलेखन: http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean) – Techwolf

-2

हां, आप अपने समग्र वस्तु साझा वरीयताओं में बचा सकता है। मान लीजिए:

Student mStudentObject = new Student(); 
    SharedPreferences appSharedPrefs = PreferenceManager 
     .getDefaultSharedPreferences(this.getApplicationContext()); 
     Editor prefsEditor = appSharedPrefs.edit(); 
     Gson gson = new Gson(); 
     String json = gson.toJson(mStudentObject); 
     prefsEditor.putString("MyObject", json); 
     prefsEditor.commit(); 

और अब आप के रूप में अपने वस्तु प्राप्त कर सकते हैं:

 SharedPreferences appSharedPrefs = PreferenceManager 
    .getDefaultSharedPreferences(this.getApplicationContext()); 
    Editor prefsEditor = appSharedPrefs.edit(); 
    Gson gson = new Gson(); 
    String json = appSharedPrefs.getString("MyObject", ""); 
    Student mStudentObject = gson.fromJson(json, Student.class); 
+1

ऐसा करने का बुरा विचार - इस पर निर्भर करता है सूची का आकार बचाया जा रहा है। साझा संदर्भ एक एक्सएमएल फ़ाइल है, यह विशाल डेटा सेट के भंडारण के लिए डिज़ाइन नहीं किया गया है। – mwieczorek