रोटेशन Android पर गतिविधि पुनः आरंभ


1379

मेरे एंड्रॉइड एप्लिकेशन में, जब मैं डिवाइस को घुमाता हूं (कीबोर्ड को बाहर स्लाइड करता है) तो मेरा Activityपुनरारंभ होता है ( onCreateइसे कहा जाता है)। अब, यह शायद यह है कि यह कैसे माना जाता है, लेकिन मैं इस onCreateपद्धति में बहुत सारी प्रारंभिक सेटिंग करता हूं, इसलिए मुझे इसकी आवश्यकता है:

  1. सभी प्रारंभिक सेटिंग को किसी अन्य फ़ंक्शन में रखें ताकि यह सभी डिवाइस रोटेशन पर खो न जाए या
  2. इसे onCreateफिर से करें और फिर लेआउट केवल समायोजित या नहीं कहा जाता है
  3. ऐप को सिर्फ पोर्ट्रेट तक सीमित रखें ताकि onCreateइसे कॉल न किया जाए ।

4
इस ब्लॉग पोस्ट में गतिविधि कॉन्फ़िगरेशन परिवर्तनों के दौरान लंबे समय तक चलने वाले अतुल्यकालिक कार्यों को कैसे बनाए रखा जाए, इस पर एक पूर्ण विवरण है!
एड्रियन मॉन्क

3
यह एक सीधा जवाब नहीं है जैसा कि दूसरों ने पहले ही उत्तर दिया है, लेकिन मैं आपको जीवन चक्र के संबंध में आपके एंड्रॉइड ऐप्स में क्या होता है, यह समझने के लिए LogLifeCycle पर एक नज़र डालने के लिए आमंत्रित करता हूं ।
Snicolas

जवाबों:


965

अनुप्रयोग वर्ग का उपयोग करना

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

public class MyApplicationClass extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    // TODO Put your application initialization code here.
  }
}

onCreateआवेदन कक्षा में केवल, जब पूरा आवेदन बनाई गई है कहा जाता है तो उन्मुखीकरण या कीबोर्ड दृश्यता परिवर्तन पर गतिविधि पुनरारंभ यह ट्रिगर नहीं करेगा।

इस वर्ग के उदाहरण को एक सिंगलटन के रूप में उजागर करना और एप्लिकेशन वेरिएबल्स को उजागर करना अच्छा है जो आप गेटर्स और सेटर्स का उपयोग करके आरंभ कर रहे हैं।

नोट: आपको इसे पंजीकृत करने और उपयोग करने के लिए प्रकट में अपने नए एप्लिकेशन वर्ग का नाम निर्दिष्ट करना होगा:

<application
    android:name="com.you.yourapp.MyApplicationClass"

कॉन्फ़िगरेशन परिवर्तन पर प्रतिक्रिया [अद्यतन: यह एपीआई 13 के बाद से हटा दिया गया है; अनुशंसित विकल्प देखें ]

एक और विकल्प के रूप में, आप अपने एप्लिकेशन को उन घटनाओं के लिए सुन सकते हैं जो पुनः आरंभ करने का कारण बनेगी - जैसे अभिविन्यास और कीबोर्ड दृश्यता परिवर्तन - और उन्हें अपनी गतिविधि के भीतर संभालें।

android:configChangesअपनी गतिविधि के प्रकट नोड में नोड जोड़कर प्रारंभ करें

 <activity android:name=".MyActivity"
      android:configChanges="orientation|keyboardHidden"
      android:label="@string/app_name">

या Android 3.2 (एपीआई स्तर 13) और नए के लिए :

<activity android:name=".MyActivity"
      android:configChanges="keyboardHidden|orientation|screenSize"
      android:label="@string/app_name">

फिर गतिविधि के भीतर onConfigurationChangedविधि को ओवरराइड करें और setContentViewनए ओरिएंटेशन में GUI लेआउट को फिर से करने के लिए मजबूर करने के लिए कॉल करें ।

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  setContentView(R.layout.myLayout);
}

17
मुझे नहीं लगता कि दूसरा दृष्टिकोण काम करता है। मैं इसे करने की कोशिश की; एक EditText के साथ एक गतिविधि। मैंने वहां कुछ पाठ लिखा, अभिविन्यास बदला और पाठ चला गया / रीसेट।
टेड

231
यहाँ उम्मीद है कि हम भविष्य में एक ऑनरेट () पद्धति देखें। इस तरह की चीजों के बारे में भी चिंता करने के लिए - स्पष्ट रूप से निराशा होती है।
केली सुटन

84
ध्यान दें कि एंड्रॉइड देव गाइड इसका उपयोग करने के खिलाफ सावधान करता है: नोट: ( android:configChanges) का उपयोग करने से बचा जाना चाहिए और केवल अंतिम उपाय के रूप में उपयोग किया जाना चाहिए। कॉन्फ़िगरेशन परिवर्तन के कारण पुनरारंभ को ठीक से कैसे प्रबंधित करें, इसके बारे में अधिक जानकारी के लिए कृपया रनटाइम परिवर्तन को पढ़ें। बदले में, रोटेशन की घटनाओं में डेटा को बनाए रखने के लिए, वे का उपयोग करना पसंद करते हैं onSaveInstanceState Bundle; या के रूप में @ जॉन-ओ का उल्लेख है , onRetainNonConfigurationInstance
जेफ्रो

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

16
मुझे लगता है कि आपको इस अपडेट को अपने उत्तर में 3.2 पर जोड़ना चाहिए , यह काफी महत्वपूर्ण है (बस उस समस्या का सामना किया है) और इसे अनदेखा किया जा सकता है।
बिगस्टोन

185

Android 3.2 और उच्चतर के लिए अपडेट करें:

सावधानी : एंड्रॉइड 3.2 (एपीआई स्तर 13) के साथ शुरुआत, "स्क्रीन का आकार" भी बदलता है जब डिवाइस पोर्ट्रेट और लैंडस्केप ओरिएंटेशन के बीच स्विच करता है। इस प्रकार, यदि आप API स्तर 13 या उच्चतर (जैसा कि minSdkVersion और targetSdkVersion विशेषताओं द्वारा घोषित किया गया है) के लिए विकसित होते समय अभिविन्यास परिवर्तन के कारण रनटाइम पुनरारंभ को रोकना चाहते हैं, तो आपको "screenSize"मूल्य के अतिरिक्त मूल्य भी शामिल करना चाहिए "orientation"। यानी आपको घोषित करना होगा android:configChanges="orientation|screenSize"। हालाँकि, यदि आपका एप्लिकेशन API स्तर 12 या उससे कम का लक्ष्य करता है, तो आपकी गतिविधि हमेशा इस कॉन्फ़िगरेशन परिवर्तन को स्वयं संभालती है (यह कॉन्फ़िगरेशन परिवर्तन आपकी गतिविधि को पुनरारंभ नहीं करता है, यहां तक ​​कि एंड्रॉइड 3.2 या उच्चतर डिवाइस पर चलने पर भी)।


1
उस स्पष्टीकरण के लिए धन्यवाद, क्योंकि इस पर एक टिप्पणी के बाद मुझे लगभग इसे देखने के लिए भेज दिया गया। मैं वर्तमान में API 8 को लक्षित कर रहा हूं और मेरे कोड में configChanges पर स्क्रीनसाइज नहीं है और यह पुष्टि कर सकता है कि मेरे पास जो ICS चल रहा है उस डिवाइस पर यह ठीक (बिना री-ओरिएंटिंग) काम करता है।
कार्ल

इसे इंगित करने के लिए धन्यवाद, मेरे पास केवल एंड्रॉइड था: configChanges = "ओरिएंटेशन | स्क्रीनसाइज़" सेट, और ओरिएंटेशन स्विचिंग मेरी गतिविधि को फिर से बना रहा था, और मेरे जीवन के लिए मैं यह पता नहीं लगा सका कि क्यों!
क्रिस्टोफर पेरी

5
Android जोड़ना: configChanges का उपयोग केवल अंतिम उपाय के रूप में किया जाना चाहिए । उपयोग करने पर विचार करें Fragmentsऔर setRetainInstanceइसके बजाय।
साइमन फोर्सबर्ग

मुख्य बिंदु screenSizeएंड्रॉइड 3.2 और उच्चतर के लिए है, जिसने मेरी समस्या को हल किया, धन्यवाद!
फंतासी

127

onCreate()पूरी तरह से निकाल दिए जाने से रोकने की कोशिश करने के बजाय , शायद Bundle savedInstanceStateइस घटना में पारित होने की जाँच करने की कोशिश करें कि यह अशक्त है या नहीं।

उदाहरण के लिए, अगर मेरे पास कुछ तर्क हैं जो Activityवास्तव में बनाए जाने पर चलने चाहिए, तो प्रत्येक अभिविन्यास परिवर्तन पर नहीं, मैं केवल उस तर्क को केवल तभी चलाता हूं onCreate()जब savedInstanceStateवह शून्य है।

अन्यथा, मैं अभी भी चाहता हूं कि लेआउट उन्मुखीकरण के लिए ठीक से फिर से तैयार हो।

public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_game_list);

        if(savedInstanceState == null){
            setupCloudMessaging();
        }
}

निश्चित नहीं है कि यह अंतिम उत्तर है, लेकिन यह मेरे लिए काम करता है।


6
और आप वास्तव में राज्य को कहां बचा रहे हैं?
इवोक्स

5
यह मेरे लिए काम करने लगता है और यह अब तक की सबसे सरल विधि है। मैंने देखा कि आपको इसके लिए केवल ४ अप (५ सहित मेरा) बनाम ३ the३ उप-आवेदन के बारे में विचार के लिए मिला था, जो मुझे कहीं अधिक जटिल लगता है। क्या इस विधि का कोई नकारात्मक पहलू है?
चरण

4
इस समाधान ने मेरे लिए महान काम किया। मैं करने में सक्षम था Intent serverintent = new Intent(MainActivity.this, MessageListener.class);और startService(serverintent);एक बनाने के लिए serverSocket = new ServerSocket(0xcff2);और Socket client = serverSocket.accept();एक साथ BufferedReader(new InputStreamReader(client.getInputStream()));और मेरे एंड्रॉयड बारी बारी से और क्लाइंट / सर्वर कनेक्शन सक्रिय रखने के लिए, अभी तक जीयूआई घुमाने हो सकता था। मैन्युअल के अनुसार, जब पिछली गतिविधि बंद हो जाती है, तो SaveInstanceState को इनिशियलाइज़ किया जाता है।
फ्रेड एफ

3
मुझे समझ में नहीं आता, क्या पकड़ है? यह महान काम करता है, और किसी भी अन्य समाधानों की तुलना में बहुत कम जटिलता के साथ।
RTF

3
Android में इसे करने का सही तरीका है। मूल रूप से configChanges और सभी जो भारी, जटिल और अनावश्यक हैं, के साथ एक घूर्णन को पकड़ने के अन्य तरीके।
ल्यूक वेगनर

99

मैंने क्या किया...

गतिविधि अनुभाग में, जोड़े जाने पर:

android:configChanges="keyboardHidden|orientation"

लागू गतिविधि के लिए कोड में:

//used in onCreate() and onConfigurationChanged() to set up the UI elements
public void InitializeUI()
{
    //get views from ID's
    this.textViewHeaderMainMessage = (TextView) this.findViewById(R.id.TextViewHeaderMainMessage);

    //etc... hook up click listeners, whatever you need from the Views
}

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

    InitializeUI();
}

//this is called when the screen rotates.
// (onCreate is no longer called when screen rotates due to manifest, see: android:configChanges)
@Override
public void onConfigurationChanged(Configuration newConfig)
{
    super.onConfigurationChanged(newConfig);
    setContentView(R.layout.main);

    InitializeUI();
}

3
स्पष्ट करने के लिए: मेरे कार्यान्वयन से अब आप onCreate () और onConfigurationChanged () में चर आरंभीकरण कर सकते हैं, बस स्क्रीन रोटेशन के लिए बुलाया जाएगा। आपके चरों को अब स्क्रीन घुमावों से पृथक किया गया है ;-) अच्छा और ईज़
किसी ने कहीं

2
मैंने यहां वर्णित के रूप में सब कुछ किया था, लेकिन मुझे NullPointerException मिलती है जब मैं अभिविन्यास परिवर्तन के बाद एक बटन दबाने की कोशिश करता हूं। क्या गलत हो सकता है?
फिनबॉय 11

5
ध्यान रखें कि मेरा उत्तर 3 साल पुराना है और एंड्रॉइड विकसित हो रहा है ... साइमन - क्या आपके पास नमूना कोड का लिंक है? यही लोगों की जरूरत है।
कोई

3
एंड्रॉइड के खिलाफ चेतावनी देते समय: configChanges, @ SimonAndréForsberg वास्तव में सिर्फ एंड्रॉइड डॉक्स को पैराफ्रेस कर रहा है । हैंडलिंग रनटाइम परिवर्तन विकल्प (नमूना कोड सहित) पर अधिक विस्तृत जानकारी है।
लीफ अर्ने स्टॉर्सेट

67

आप जो वर्णन करते हैं वह डिफ़ॉल्ट व्यवहार है। आपको इन घटनाओं को जोड़कर स्वयं का पता लगाना और संभालना है:

android:configChanges

अपने प्रकटीकरण और फिर उन परिवर्तनों को जिन्हें आप संभालना चाहते हैं। अभिविन्यास के लिए, आप उपयोग करेंगे:

android:configChanges="orientation"

और आपके द्वारा उपयोग किए जाने वाले कीबोर्ड को खोलने या बंद करने के लिए:

android:configChanges="keyboardHidden"

यदि आप दोनों को संभालना चाहते हैं तो आप उन्हें पाइप कमांड से अलग कर सकते हैं जैसे:

android:configChanges="keyboardHidden|orientation"

यह आपके द्वारा कॉल की जाने वाली गतिविधि में onConfigurationChanged विधि को ट्रिगर करेगा। यदि आप उस विधि को ओवरराइड करते हैं जो आप नए मूल्यों में पारित कर सकते हैं।

उम्मीद है की यह मदद करेगा।


2
@GregD मुझे पता है, यही वजह है कि आज की स्थिति को प्रतिबिंबित करने के लिए इसे अपडेट करने का एक अच्छा समय है। इस प्रश्न की संख्या को देखते हुए, इसे अभी भी SO पर अन्य प्रश्नों से संदर्भित किया जा रहा है।
साइमन फोर्सबर्ग

48

मैंने इस विद्या की खोज की:

एक अभिविन्यास परिवर्तन के माध्यम से गतिविधि को जीवित रखने के लिए, और इसके माध्यम से संभालना onConfigurationChanged, प्रलेखन और ऊपर दिए गए कोड नमूने को मैनिफ़ेस्ट फ़ाइल में यह सुझाव देते हैं:

<activity android:name=".MyActivity"
      android:configChanges="orientation|keyboardHidden"
      android:label="@string/app_name">

जिसका अतिरिक्त लाभ है कि यह हमेशा काम करता है।

बोनस विद्या यह है कि छूटना keyboardHiddenतर्कसंगत लग सकता है, लेकिन यह एमुलेटर में विफलताओं का कारण बनता है (एंड्रॉइड 2.1 के लिए कम से कम): निर्दिष्ट orientationकरने से एमुलेटर कॉल केवल OnCreateऔर onConfigurationChangedकभी-कभी, और केवलOnCreate अन्य बार ।

मैंने किसी उपकरण पर विफलता नहीं देखी है, लेकिन मैंने दूसरों के लिए एमुलेटर के बारे में सुना है। तो यह दस्तावेज के लायक है।


14
सावधानी: एंड्रॉइड 3.2 (एपीआई स्तर 13) के साथ शुरुआत, "स्क्रीन का आकार" भी बदलता है जब डिवाइस पोर्ट्रेट और लैंडस्केप ओरिएंटेशन के बीच स्विच करता है। इस प्रकार, यदि आप API स्तर 13 या उच्चतर के लिए विकसित होने पर अभिविन्यास परिवर्तन के कारण रनटाइम पुनरारंभ को रोकना चाहते हैं: Android: configChanges = "ओरिएंटेशन; कीबोर्डहाइन्ड | स्क्रीनसेज़"
Geltrude

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

Android जोड़ना: configChanges का उपयोग केवल अंतिम उपाय के रूप में किया जाना चाहिए । उपयोग करने पर विचार करें Fragmentsऔर setRetainInstanceइसके बजाय।
साइमन फोर्सबर्ग

38

आप ओरिएंटेशन परिवर्तनों में डेटा को जारी रखने के लिए एंड्रॉइड प्लेटफ़ॉर्म के तरीके का उपयोग करने पर भी विचार कर सकते हैं: onRetainNonConfigurationInstance()और getLastNonConfigurationInstance()

यह आपको कॉन्फ़िगरेशन परिवर्तन के दौरान डेटा को बनाए रखने की अनुमति देता है, जैसे कि जानकारी आपको सर्वर से प्राप्त हो सकती है या कुछ और जो कि इसमें onCreateया उसके बाद से गणना की गई है , जबकि एंड्रॉइड भी Activityअब उन्मुखीकरण के लिए xml फ़ाइल का उपयोग करके अपने लेआउट को फिर से लेआउट करने की अनुमति देता है ।

यहाँ या यहाँ देखें ।

यह ध्यान दिया जाना चाहिए कि इन तरीकों को अब हटा दिया गया है (हालांकि अभी भी अभिविन्यास को संभालने की तुलना में अधिक लचीला है अपने आप को उपरोक्त समाधानों में से अधिकांश के रूप में बदलते हैं) इस अनुशंसा के साथ कि हर कोई स्विच करना चाहता है Fragmentsऔर इसके बजाय setRetainInstance(true)प्रत्येक Fragmentको बनाए रखना चाहता है।


3
मुझे वास्तव में लगता है कि यह करने के लिए Fragments और setRetainInstance सबसे अच्छा तरीका है (और Google द्वारा अनुशंसित तरीका), आपके लिए +1 और अन्य सभी को। एंड्रॉइड जोड़ना: configChanges का उपयोग केवल अंतिम उपाय के रूप में किया जाना चाहिए
सिमोन फोर्सबर्ग

32

दृष्टिकोण उपयोगी है, लेकिन टुकड़े का उपयोग करते समय अधूरा है।

टुकड़े आमतौर पर विन्यास परिवर्तन पर पुनर्निर्मित होते हैं। यदि आप ऐसा होने की इच्छा नहीं रखते हैं, तो उपयोग करें

setRetainInstance(true); फ्रैगमेंट के निर्माता में

यह कॉन्फ़िगरेशन परिवर्तन के दौरान टुकड़ों को बनाए रखने का कारण होगा।

http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)


7
माना। नवीनतम एंड्रॉइड एपीआई के साथ, ऐसा लगता है कि फ्रेगमेंट इसे संभालने का सही तरीका है। मैंने इसे अभी तक स्वयं आज़माया नहीं है, लेकिन इस पृष्ठ को पढ़कर जो मैंने इकट्ठा किया है , आप मूल रूप से किसी गतिविधि में किसी फ़्रैगमेंट के उपवर्ग में 99% का उपयोग करते हैं, फिर उस फ़्रैगमेंट को गतिविधि में जोड़ें। गतिविधि अभी भी नष्ट हो जाएगी और स्क्रीन रोटेशन पर फिर से बनाई जाएगी, लेकिन आप विशेष रूप से एंड्रॉइड को बता सकते हैं कि विधि @Abdo का उपयोग करके फ्रैगमेंट को नष्ट करें setRetainInstance()
ब्रायनमर्न्स

25

मैंने बस जोड़ा

     android:configChanges="keyboard|keyboardHidden|orientation"

मैनिफ़ेस्ट फ़ाइल में और कोई जोड़ नहीं हैonConfigurationChanged मेरी गतिविधि में विधि ।

इसलिए हर बार कीबोर्ड स्लाइड करता है या कुछ भी नहीं होता है


में जोड़ा गया है <application ...android:configChanges="keyboard|keyboardHidden|orientation">और यह काम कर रहा है। बिल्ड.ग्रेडल में मेरी सेटिंग:minSdkVersion 15, compileSdkVersion 23, buildToolsVersion "23.0.2"
जूनियर मेहे

19

onCreateपद्धति अभी भी भी कहा जाता है जब आप बदलना orientationएंड्रॉयड की। इसलिए इस पद्धति में सभी भारी कार्यक्षमता को स्थानांतरित करना आपकी मदद करने वाला नहीं है



17
 onConfigurationChanged is called when the screen rotates. 
 (onCreate is no longer called when screen rotates due to manifest, see:  
 android:configChanges)

मैनिफ़ेस्ट का कौन सा भाग इसे "कॉल न करें onCreate()" बताता है ?

इसके अलावा, Google के डॉक्स का उपयोग करने से बचने के लिए कहते हैं android:configChanges(अंतिम उपाय के रूप में छोड़कर) .... लेकिन फिर वैकल्पिक विधियां वे सभी DO उपयोग का सुझाव देते हैं android:configChanges

यह मेरा अनुभव रहा है कि एमुलेटर ALWAYS onCreate()रोटेशन पर कॉल करता है।
लेकिन 1-2 डिवाइस जो मैं एक ही कोड को चालू करता हूं ... नहीं। (यह निश्चित नहीं है कि कोई अंतर क्यों होगा।)


16

यह बहुत सरल है बस निम्नलिखित कदम करें:

<activity
    android:name=".Test"
    android:configChanges="orientation|screenSize"
    android:screenOrientation="landscape" >
</activity>

यह मेरे लिए काम करता है:

नोट: अभिविन्यास आपकी आवश्यकता पर निर्भर करता है


15

Android मेनिफेस्ट में किए जाने वाले परिवर्तन हैं:

android:configChanges="keyboardHidden|orientation" 

गतिविधि के अंदर किए जाने वाले अतिरिक्त हैं:

public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}

15

इस लाइन को अपने घोषणापत्र में जोड़ें: -

android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|uiMode"

और इस गतिविधि के लिए स्निपेट: -

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }

14

इसे करने बहुत सारे तरीके हैं:

गतिविधि राज्य सहेजें

आप गतिविधि स्थिति को सहेज सकते हैं onSaveInstanceState

@Override
public void onSaveInstanceState(Bundle outState) {
    /*Save your data to be restored here
    Example : outState.putLong("time_state", time); , time is a long variable*/
    super.onSaveInstanceState(outState);
}

और फिर bundleराज्य को पुनर्स्थापित करने के लिए उपयोग करें ।

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

    if(savedInstanceState!= null){
       /*When rotation occurs
        Example : time = savedInstanceState.getLong("time_state", 0); */
    } else {
      //When onCreate is called for the first time
    }
}

अपने आप से हैंडल ओरिएंटेशन बदलता है

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

इसे अपनी मैनिफ़ेस्ट फ़ाइल में जोड़ें।

android:configChanges="keyboardHidden|orientation"

Android के लिए 3.2 और बाद में:

android:configChanges="keyboardHidden|orientation|screenSize"

@Override
public void onConfigurationChanged(Configuration config) {
    super.onConfigurationChanged(config);

if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        //Handle rotation from landscape to portarit mode here
    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
        //Handle rotation from portrait to landscape mode here
    }
}

रोटेशन को प्रतिबंधित करें

रोटेशन से बचने के लिए आप अपनी गतिविधि को पोर्ट्रेट या लैंडस्केप मोड तक सीमित कर सकते हैं।

इसे अपनी प्रकट फ़ाइल में गतिविधि टैग में जोड़ें:

        android:screenOrientation="portrait"

या इस कार्यक्रम को अपनी गतिविधि में लागू करें:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

11

जिस तरह से मैंने ऐसा करने के लिए पाया है वह है onRestoreInstanceStateऔर onSaveInstanceStateकुछ को बचाने के लिए घटनाओं का उपयोग करें Bundle(भले ही आपको किसी भी चर को बचाने की आवश्यकता न हो, बस कुछ डाल दें ताकि वह Bundleखाली न हो)। फिर, onCreateविधि पर, यह देखने के लिए जांचें कि Bundleक्या खाली है, और यदि यह है, तो आरंभीकरण करें, यदि नहीं, तो करें।


11

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

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


मुझे इसका कुछ नमूना कोड देखना अच्छा लगेगा, शानदार लगता है!
हेनरिक डी सूसा

8

हर बार जब स्क्रीन को घुमाया जाता है, तो खुली हुई गतिविधि समाप्त हो जाती है और ऑनक्रिएट () फिर से कहा जाता है।

1 है। जब स्क्रीन को घुमाया जाता है, तो आप गतिविधि की स्थिति को बचाने के लिए एक कार्य कर सकते हैं, ताकि गतिविधि के ऑनक्रिएट () को फिर से कॉल करने पर आप सभी पुराने सामान को पुनर्प्राप्त कर सकें। देखें इस लिंक को

२। यदि आप गतिविधि को फिर से शुरू करने से रोकना चाहते हैं, तो अपनी मैनिफ़ेस्ट.xml फ़ाइल में निम्न पंक्तियाँ रखें।

  <activity android:name=".Youractivity"
  android:configChanges="orientation|screenSize"/>

7

आपको अपने पैरामीटर के सभी मान को संग्रहीत करने के लिए onSavedInstanceState विधि का उपयोग करने की आवश्यकता है जो बंडल है

@Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        outPersistentState.putBoolean("key",value);
    }

और उपयोग करें

@Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        savedInstanceState.getBoolean("key");
    } 

उन वस्तुओं को देखने के लिए मूल्य को वापस लेने और सेट करने के लिए जो यह स्क्रीन घुमाव को संभालती है


इसके लिए एपीआई स्तर 22 की जरूरत है।
मोहम्मद अफरासतेह

6

नोट: मैं इस उत्तर को पोस्ट करता हूं यदि भविष्य में कोई मेरे समान समस्या का सामना करता है। मेरे लिए निम्नलिखित पंक्ति पर्याप्त नहीं थी:

android:configChanges="orientation"

जब मैंने स्क्रीन को घुमाया, तो विधि `onConfigurationChanged (कॉन्फ़िगरेशन newConfig) को कॉल नहीं किया गया।

समाधान: मुझे "स्क्रीनसेज़" भी जोड़ना था, भले ही समस्या को उन्मुखीकरण के साथ करना था। तो AndroidManifest.xml - फ़ाइल में, इसे जोड़ें:

android:configChanges="keyboardHidden|orientation|screenSize"

फिर विधि को लागू करें onConfigurationChanged(Configuration newConfig)




4

लोग कह रहे हैं कि आपको उपयोग करना चाहिए

android:configChanges="keyboardHidden|orientation"

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

बेशक, दूसरे तरीके के रूप में, आप मूल्यों या विचारों को onSaveInstanceState के साथ संग्रहीत कर सकते हैं और उन्हें onRestoreInstanceState के साथ पढ़ सकते हैं। यह वास्तव में आप पर निर्भर है।


हाँ, चलो "पेशेवर" दिखने के लिए अतिरिक्त कोड के gobs जोड़ें। या कैसे के बारे में सिर्फ त्वरित, आसान, सच्चा और कोशिश की तरह इसे कॉन्फ़िगरेशनचैनेज विशेषता के साथ छड़ी।
AndroidDev

3

परीक्षण और त्रुटि के कुछ समय बाद, मुझे एक समाधान मिला जो मेरी स्थितियों में सबसे अधिक मेरी आवश्यकताओं के अनुरूप है। यहाँ कोड है:

प्रकट विन्यास:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.pepperonas.myapplication">

    <application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

मुख्य गतिविधि:

import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "MainActivity";

    private Fragment mFragment;

    private int mSelected = -1;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate  " + "");

        // null check not realy needed - but just in case...
        if (savedInstanceState == null) {

            initUi();

            // get an instance of FragmentTransaction from your Activity
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

            /*IMPORTANT: Do the INITIAL(!) transaction only once!
            * If we call this everytime the layout changes orientation,
            * we will end with a messy, half-working UI.
            * */
            mFragment = FragmentOne.newInstance(mSelected = 0);
            fragmentTransaction.add(R.id.frame, mFragment);
            fragmentTransaction.commit();
        }
    }


    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.d(TAG, "onConfigurationChanged  " +
                   (newConfig.orientation
                    == Configuration.ORIENTATION_LANDSCAPE
                    ? "landscape" : "portrait"));

        initUi();

        Log.i(TAG, "onConfigurationChanged - last selected: " + mSelected);
        makeFragmentTransaction(mSelected);
    }


    /**
     * Called from {@link #onCreate} and {@link #onConfigurationChanged}
     */
    private void initUi() {
        setContentView(R.layout.activity_main);
        Log.d(TAG, "onCreate  instanceState == null / reinitializing..." + "");
        Button btnFragmentOne = (Button) findViewById(R.id.btn_fragment_one);
        Button btnFragmentTwo = (Button) findViewById(R.id.btn_fragment_two);
        btnFragmentOne.setOnClickListener(this);
        btnFragmentTwo.setOnClickListener(this);
    }


    /**
     * Not invoked (just for testing)...
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.d(TAG, "onSaveInstanceState  " + "YOU WON'T SEE ME!!!");
    }


    /**
     * Not invoked (just for testing)...
     */
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.d(TAG, "onSaveInstanceState  " + "YOU WON'T SEE ME, AS WELL!!!");
    }


    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume  " + "");
    }


    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause  " + "");
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy  " + "");
    }


    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.btn_fragment_one:
                Log.d(TAG, "onClick btn_fragment_one " + "");
                makeFragmentTransaction(0);
                break;

            case R.id.btn_fragment_two:
                Log.d(TAG, "onClick btn_fragment_two " + "");
                makeFragmentTransaction(1);
                break;

            default:
                Log.d(TAG, "onClick  null - wtf?!" + "");
        }
    }


    /**
     * We replace the current Fragment with the selected one.
     * Note: It's called from {@link #onConfigurationChanged} as well.
     */
    private void makeFragmentTransaction(int selection) {

        switch (selection) {
            case 0:
                mFragment = FragmentOne.newInstance(mSelected = 0);
                break;
            case 1:
                mFragment = FragmentTwo.newInstance(mSelected = 1);
                break;
        }

        // Create new transaction
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        // Replace whatever is in the fragment_container view with this fragment,
        // and add the transaction to the back stack
        transaction.replace(R.id.frame, mFragment);

        /*This would add the Fragment to the backstack...
        * But right now we comment it out.*/
        //        transaction.addToBackStack(null);

        // Commit the transaction
        transaction.commit();
    }

}

और नमूना टुकड़ा:

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

/**
 * @author Martin Pfeffer (pepperonas)
 */
public class FragmentOne extends Fragment {

    private static final String TAG = "FragmentOne";


    public static Fragment newInstance(int i) {
        Fragment fragment = new FragmentOne();
        Bundle args = new Bundle();
        args.putInt("the_id", i);
        fragment.setArguments(args);
        return fragment;
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView  " + "");
        return inflater.inflate(R.layout.fragment_one, container, false);
    }

}

गितुब पर पाया जा सकता है ।


3

orientationविभिन्न अभिविन्यास पर विभिन्न कार्यों को करने के लिए श्रोता का उपयोग करें ।

@Override
public void onConfigurationChanged(Configuration myConfig) 
{
    super.onConfigurationChanged(myConfig);
    int orient = getResources().getConfiguration().orientation; 
    switch(orient) 
    {
       case Configuration.ORIENTATION_LANDSCAPE:
          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                    break;
       case Configuration.ORIENTATION_PORTRAIT:
          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                    break;
       default:
          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
    }
}

3

इस नीचे दिए गए कोड को अपने Activityअंदर डालें Android Manifest

android:configChanges="orientation"

जब आप अभिविन्यास को बदलेंगे, तो यह आपकी गतिविधि को फिर से शुरू नहीं करेगा।


2
@ मेवामार्टन संभवतः क्योंकि अन्य ने इंगित किया है, यह बुरा व्यवहार है और दस अन्य उत्तर पहले ही इसे कवर कर चुके हैं।
मिककोप

3

में स्क्रीन ओरिएंटेशन (लैंडस्केप या पोर्ट्रेट) को ठीक करें AndroidManifest.xml

android:screenOrientation="portrait" या android:screenOrientation="landscape"

इसके लिए आपकी onResume()विधि को नहीं कहा जाता है।


5
कैसे कुछ ठीक कर नरक एक जवाब है? यदि हम उपयोगकर्ताओं को इसका उपयोग करने से रोकते हैं तो हमारे उपकरण क्यों घूम सकते हैं?
रेनहार्ड

3

Google द्वारा एंड्रॉइड आर्किटेक्योर परिचय का एक सबसे अच्छा घटक आपकी सभी आवश्यकता को पूरा करेगा जो कि ViewModel है।

इसे जीवन चक्र में यूआई से संबंधित डेटा को स्टोर करने और प्रबंधित करने के लिए डिज़ाइन किया गया है, जिससे डेटा स्क्रीन रोटेट के रूप में जीवित रह सकेगा

class MyViewModel : ViewModel() {

कृपया इसे देखें: https://developer.android.com/topic/lbooks/altecture/viewmodel


1

आप अपनी गतिविधि में ViewModel ऑब्जेक्ट का उपयोग कर सकते हैं।

ViewModel ऑब्जेक्ट कॉन्फ़िगरेशन परिवर्तन के दौरान स्वचालित रूप से बनाए रखा जाता है ताकि वे जो डेटा रखते हैं वह तुरंत अगली गतिविधि या खंड उदाहरण के लिए उपलब्ध हो। अधिक पढ़ें:

https://developer.android.com/topic/libraries/architecture/viewmodel

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