एंड्रॉइड में लेआउट में अभिविन्यास परिवर्तन का पता कैसे लगाएं?


110

मैंने अभी एक अभिविन्यास परिवर्तन सुविधा लागू की है - उदाहरण के लिए जब लेआउट चित्र से परिदृश्य में बदलता है (या इसके विपरीत)। जब अभिविन्यास परिवर्तन ईवेंट समाप्त हो जाता है तो मैं कैसे पता लगा सकता हूं।

OrientationEventListenerकाम नहीं किया। मैं लेआउट ओरिएंटेशन परिवर्तन घटनाओं के बारे में सूचनाएं कैसे प्राप्त कर सकता हूं?


मेरे मामले में, अभिविन्यास में परिवर्तन होने पर onCreate () कहा जाता था।
जोसियल नोवाज़

जवाबों:


293

गतिविधि के onConfigurationChanged विधि का उपयोग करें । निम्नलिखित कोड देखें:

@Override
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();
    }
}

आपको उपयुक्त को भी संपादित करना होगा एंड्रॉइड शामिल करने के लिए आपकी मैनिफ़ेस्ट फ़ाइल में तत्व : configChanges बस नीचे दिए गए कोड को देखें:

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

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

आशा है कि यह आपकी मदद करेगा... :)


3
यह अच्छा है, लेकिन यह लेआउट xml लेआउट-लैंड फ़ोल्डर में चित्र xml लेआउट फ़ाइलों का उपयोग करता है लोड करता है।
प्रोग्रामर

22
एज़्टेक कोडर, जब आप "android: configChanges =" ओरिएंटेशन शामिल करते हैं, तो आप घोषणा कर रहे हैं कि आप ओरिएंटेशन परिवर्तन को संभाल लेंगे, जिसका अर्थ है कि जब आप लैंडस्केप पर स्विच करते हैं तो आपकी गतिविधि फिर से तैयार नहीं होगी। इसके बजाय, ऑनकोनफिगरेशनचेंज को कहा जाता है। यदि यह अवांछित है। , आप अपनी गतिविधि के उन्मुखीकरण को याद करने के लिए एक चर का उपयोग कर सकते हैं और हर बार जब आप जाते हैं (उदाहरण के लिए) यह जांचने के लिए कि क्या अभिविन्यास अभी भी वही है।
ऐलेना

14
यदि आप API स्तर 13 (3.2) या उच्चतर के लिए विकसित कर रहे हैं, तो आपको Android निर्दिष्ट करना चाहिए: configChanges = "ओरिएंटेशन। स्क्रीनाइज़ करें", अन्यथा onConfigurationChanged नहीं कहा जाएगा: developer.android.com/guide/topics-resource/…
Arne

1
नमस्ते, मैं एपीआई 10 (Android 2.3.3) के साथ अपना ऐप बना रहा हूं। और यह पूरी तरह से अभिविन्यास को पहचानता है जब मैं एंड्रॉइड का उपयोग करता हूं: configChanges = "अभिविन्यास | कीबोर्डहाइड"। लेकिन मेरा नेक्सस एस जो कि एंड्रॉइड 4.1.2 चलाता है, अभिविन्यास परिवर्तन का पता नहीं लगाता है। मुझे क्या करना चाहिए?
कार्तिक आन्दमिल

2
एंड्रॉइड का उपयोग करें : configChanges = "अभिविन्यास | screenSize" Android के बजाय : configChanges = "ओरिएंटेशन; कीबोर्डहेड" अपनी मैनिफ़ेस्ट फ़ाइल में और जांचें ... !!!
दिनेश शर्मा

15

में लेआउट लोड करने के लिए लेआउट भूमि फ़ोल्डर साधन आप दो अलग-अलग लेआउट तो आप करना है setContentViewमें onConfigurationChangedविधि।

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

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        setContentView(R.layout.yourxmlinlayout-land);
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        setContentView(R.layout.yourxmlinlayoutfolder);
    }
}

यदि आपके पास केवल एक लेआउट है तो इस विधि में setContentView बनाने के लिए आवश्यक नहीं है। केवल

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

19
ओवरराइड करने के बजाय, केवल लेआउट / main.xml और लेआउट-लैंड / main.xml का उपयोग करें।
जारेड बुरो

@JaredBurrows: कृपया देखें stackoverflow.com/questions/23789605/…
बी क्ले शैनन

मैं यह पता लगाना चाहता था कि स्क्रीन के घूमने के कारण मेरी गतिविधि समाप्त हो गई है या नहीं। मैंने onConfigurationChanged(Configuration newConfig)विधि को लागू किया (जैसा कि इस उत्तर में है), लेकिन खुद को संभालने के बजाय, मैंने बूलियन ध्वज सेट किया और फिर recreate()विधि को बुलाया ताकि एंड्रॉइड ने अपने सामान्य फैशन में गतिविधि को फिर से बनाया।
स्तब्ध

recreate()विधि के साथ एक समस्या यह है कि यह स्क्रीन को संक्षिप्त रूप से फ्लैश करने का कारण बनता है। इस कारण से मैंने एक और दृष्टिकोण का उपयोग किया: (1) में स्क्रीन की चौड़ाई को बचाने के लिए onCreate(...)(2) किसी भी जीवन-चक्र विधि में सहेजे गए स्क्रीन की चौड़ाई की तुलना करें जब गतिविधि समाप्त हो रही हो (जैसे onSaveInstanceState(...))।
चकित

13

बस आपको onConfigurationChanged के बाद अपने सभी बंडल को सहेजने का एक तरीका दिखाना था:

अपनी कक्षा के ठीक बाद नया बंडल बनाएँ:

public class MainActivity extends Activity {
    Bundle newBundy = new Bundle();

अगला, "संरक्षित शून्य onCreate" के बाद इसे जोड़ें:

@Override
public void onConfigurationChanged(Configuration newConfig) {
     super.onConfigurationChanged(newConfig);
     if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            onSaveInstanceState(newBundy);
        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            onSaveInstanceState(newBundy);
        }
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBundle("newBundy", newBundy);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    savedInstanceState.getBundle("newBundy");
}

यदि आप अपने सभी क्रेट किए गए वर्गों को मेनऐक्टीविटी में जोड़ देते हैं तो बच जाएंगे।

लेकिन सबसे अच्छा तरीका यह है कि आप इसे अपने AndroidManifest में जोड़ें:

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

7
यह भ्रामक है। लागू करना onConfigurationChanged()इसे बनाता है ताकि अभिविन्यास में परिवर्तन होने पर आपका इंस्टैस्टेट नष्ट न हो, इसलिए आपको इसे बचाने की आवश्यकता नहीं है। आप इसे गतिविधि जीवन चक्र में अन्य घटनाओं के लिए सहेजना चाह सकते हैं, लेकिन मुझे नहीं पता।
इजी जूल

5

इस विधि का उपयोग करें

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)
    {
        Toast.makeText(getActivity(),"PORTRAIT",Toast.LENGTH_LONG).show();
       //add your code what you want to do when screen on PORTRAIT MODE
    }
    else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
    {
        Toast.makeText(getActivity(),"LANDSCAPE",Toast.LENGTH_LONG).show();
        //add your code what you want to do when screen on LANDSCAPE MODE
   }
}

और अपने Androidmainfest.xml में इसे जोड़ना न भूलें

android:configChanges="orientation|screenSize"

इस तरह

<activity android:name=".MainActivity"
          android:theme="@style/Theme.AppCompat.NoActionBar"
          android:configChanges="orientation|screenSize">

    </activity>

2

गतिविधि की विधि को ओवरऑनफिगरेशन को ओवरराइड करें


मैं यह बताना चाहूंगा कि प्रकट में <गतिविधि> टैग के अंदर निम्नलिखित पंक्ति के बिना, ऑनकोनफिगरेशनचैनेज () कॉल बैक भी ट्रिगर नहीं होगा। Android: configChanges = "अभिविन्यास"
श्रीकांत करुमनघाट

1

मैं सिर्फ एक और विकल्प का प्रस्ताव करना चाहता हूं जो कि आप में से कुछ को चिंतित करेगा, जैसा कि ऊपर बताया गया है:

android:configChanges="orientation|keyboardHidden" 

तात्पर्य यह है कि हम स्पष्ट रूप से लेआउट को इंजेक्ट करने की घोषणा करते हैं।

मामले में हम लेआउट और भूमि और लेआउट फ़ोल्डरों के लिए स्वचालित इंजेक्शन धन्यवाद रखना चाहते हैं। आपको बस इसे ऑनक्रिएट में जोड़ना है:

    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
        getSupportActionBar().hide();

    } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
        getSupportActionBar().show();
    }

यहां, हम फोन के उन्मुखीकरण के आधार पर एक्शनबार प्रदर्शित करते हैं या नहीं


0

OrientationEventListenerकक्षा का एक उदाहरण बनाएं और इसे सक्षम करें।

OrientationEventListener mOrientationEventListener = new OrientationEventListener(YourActivity.this) {
    @Override
    public void onOrientationChanged(int orientation) {
        Log.d(TAG,"orientation = " + orientation);
    }
};

if (mOrientationEventListener.canDetectOrientation())
    mOrientationEventListener.enable();

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

0

यदि स्वीकृत उत्तर आपके लिए काम नहीं करता है, तो सुनिश्चित करें कि आपने प्रकट फ़ाइल में परिभाषित नहीं किया है:

android:screenOrientation="portrait"

जो मेरा मामला है।


0

मामले में यह कुछ नए देव के लिए उपयोग का है क्योंकि इसके ऊपर निर्दिष्ट नहीं किया गया है। बस बहुत स्पष्ट होना चाहिए:

ऑनकोनफिगरेशनचेंज किए जाने पर आपको दो चीजों की जरूरत है :

  1. onConfigurationChangedआपकी गतिविधि कक्षा में एक विधि

  2. अपने मेनिफेस्ट में निर्दिष्ट करें कि कौन से कॉन्फ़िगरेशन परिवर्तन आपकी विधि द्वारा नियंत्रित किए जाएंगेonConfigurationChanged

उपरोक्त उत्तरों में प्रकट स्निपेट, जबकि प्रकट होने वाले किसी विशेष एप्लिकेशन के लिए कोई संदेह सही नहीं है, यह बिल्कुल नहीं है कि आपको अपनी गतिविधि कक्षा में ऑनकोनफिगरेशनचेंज्ड विधि को ट्रिगर करने के लिए अपने मेनिफ़ेस्ट में जोड़ने की आवश्यकता है । यानी नीचे दी गई घोषणा प्रविष्टि आपके ऐप के लिए सही नहीं हो सकती है।

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

उपरोक्त प्रकट प्रविष्टि में, विभिन्न एंड्रॉइड क्रियाएं हैं, android:configChanges=""जिनके लिए आपकी गतिविधि जीवनचक्र में onCreate को ट्रिगर किया जा सकता है।

यह बहुत महत्वपूर्ण है - प्रकट में निर्दिष्ट नहीं होने वाले वही हैं जो आपके ऑनक्रिएट को ट्रिगर करते हैं और जो मेनिफेस्ट में निर्दिष्ट हैं वे वही हैं जोonConfigurationChanged आपकी गतिविधि कक्षा में आपके तरीके को ट्रिगर करते हैं

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

<activity name= ".MainActivity" android:configChanges="screenLayout|touchscreen|mnc|mcc|density|uiMode|fontScale|orientation|keyboard|layoutDirection|locale|navigation|smallestScreenSize|keyboardHidden|colorMode|screenSize"/>

अब जाहिर है कि मैं सब कुछ संभालना नहीं चाहता, इसलिए मैंने उपरोक्त विकल्पों को एक समय में समाप्त करना शुरू कर दिया। प्रत्येक हटाने के बाद मेरे ऐप का पुनः निर्माण और परीक्षण करना।

एक और महत्वपूर्ण बिंदु : यदि आपके पास केवल एक कॉन्फ़िगरेशन विकल्प होता है जो स्वचालित रूप से आपके ऑनक्रीट को ट्रिगर करता है (आपके पास इसके ऊपर आपके प्रकट में सूचीबद्ध नहीं है), तो ऐसा लगेगा जैसे onConfigurationChangedकाम नहीं कर रहा है। आपको सभी प्रासंगिक लोगों को अपनी अभिव्यक्ति में लाना होगा।

मैं 3 के साथ समाप्त हुआ जो मूल रूप से onCreate को ट्रिगर कर रहे थे, फिर मैंने एक S10 + पर परीक्षण किया और मुझे अभी भी onCreate मिल रहा था, इसलिए मुझे अपना उन्मूलन अभ्यास फिर से करना पड़ा और मुझे इसकी आवश्यकता भी थी |screenSize। इसलिए प्लेटफार्मों के चयन पर परीक्षण करें।

<activity name= ".MainActivity" android:configChanges="screenLayout|uiMode|orientation|screenSize"/>

इसलिए मेरा सुझाव है, हालांकि मुझे यकीन है कि कोई इसमें छेद कर सकता है:

  1. onConfigurationChangedअपनी गतिविधि कक्षा में एक टोस्ट या लॉग के साथ अपनी विधि जोड़ें ताकि आप देख सकें कि कब यह काम कर रहा है।

  2. अपने प्रकट करने के लिए सभी संभव कॉन्फ़िगरेशन विकल्प जोड़ें।

  3. पुष्टि करें कि आपका onConfigurationChangedतरीका आपके ऐप का परीक्षण करके काम कर रहा है।

  4. प्रत्येक समय के बाद अपने एप्लिकेशन का परीक्षण करते हुए, अपनी मैनिफ़ेस्ट फ़ाइल से प्रत्येक कॉन्फ़िगरेशन विकल्प को निकालें।

  5. संभव के रूप में बड़े उपकरणों की एक किस्म पर परीक्षण करें।

  6. अपनी प्रकट फ़ाइल के ऊपर मेरे स्निपेट को कॉपी / पेस्ट न करें। एंड्रॉइड अपडेट सूची को बदलते हैं, इसलिए यह सुनिश्चित करने के लिए पॉप-आउट एंड्रॉइड स्टूडियो संकेत का उपयोग करें कि आप उन सभी को प्राप्त करते हैं।

मुझे आशा है कि यह किसी को कुछ समय बचाता है।

onConfigurationChangedनीचे दी गई जानकारी के लिए मेरा तरीका। नई अभिविन्यास उपलब्ध होने के बादonConfigurationChanged जीवनचक्र में कहा जाता है, लेकिन इससे पहले कि यूआई को फिर से बनाया गया है। इसलिए मेरा पहला ओरिएंटेशन काम करता है सही ढंग से जांच करने के लिए, और फिर मेरे UI ImageView की दृश्यता को देखने के लिए 2 नेस्टेड भी सही ढंग से काम करता है।ifif

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

        // Checks the orientation of the screen
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            pokerCardLarge = findViewById(R.id.pokerCardLgImageView);

            if(pokerCardLarge.getVisibility() == pokerCardLarge.VISIBLE){
                Bitmap image = ((BitmapDrawable)pokerCardLarge.getDrawable()).getBitmap();
                pokerCardLarge.setVisibility(pokerCardLarge.VISIBLE);
                pokerCardLarge.setImageBitmap(image);
            }

        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
            pokerCardLarge = findViewById(R.id.pokerCardLgImageView);

            if(pokerCardLarge.getVisibility() == pokerCardLarge.VISIBLE){
                Bitmap image = ((BitmapDrawable)pokerCardLarge.getDrawable()).getBitmap();
                pokerCardLarge.setVisibility(pokerCardLarge.VISIBLE);
                pokerCardLarge.setImageBitmap(image);
            }

        }
    }

0

कोटलिन को सरलतम रूप में लागू करने के लिए - केवल आग जब चित्र से स्क्रीन बदलती है <-> परिदृश्य अगर डिवाइस की जरूरत है एक फ्लिप पहचान (180 डिग्री) आप गुरुत्वाकर्षण सेंसर मूल्यों में टैब की आवश्यकता होगी

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

val rotation = windowManager.defaultDisplay.rotation

    when (rotation) {            
        0 -> Log.d(TAG,"at zero degree")
        1 -> Log.d(TAG,"at 270 degree")
        2 -> Log.d(TAG,"at 180 degree")
        3 -> Log.d(TAG,"at 90 degree")


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