How to detect orientation change in layout in Android?

后端 未结 10 2171
挽巷
挽巷 2020-11-22 09:36

I just implemented a orientation change feature - e.g. when the layout changes from portrait to landscape (or vice versa). How can I detect when the orientation change event

相关标签:
10条回答
  • 2020-11-22 09:56

    for Kotilin implementation in the simplest form - only fires when screen changes from portrait <--> landscape if need device a flip detection (180 degree) you'll need to tab in to gravity sensor values

    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")
    
    
        }
    }
    
    0 讨论(0)
  • 2020-11-22 09:57

    For loading the layout in layout-land folder means you have two separate layouts then you have to make setContentView in onConfigurationChanged method.

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

    If you have only one layout then no necessary to make setContentView in This method. simply

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }
    
    0 讨论(0)
  • 2020-11-22 09:57

    In case this is of use to some newer dev's because its not specified above. Just to be very explicit:

    You need two things if using onConfigurationChanged:

    1. An onConfigurationChanged method in your Activity Class

    2. Specify in your manifest which configuration changes will be handled by your onConfigurationChanged method

    The manifest snippet in the above answers, while no doubt correct for the particular app that manifest belongs to, is NOT exactly what you need to add in your manifest to trigger the onConfigurationChanged method in your Activity Class. i.e. the below manifest entry may not be correct for your app.

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

    In the above manifest entry, there are various Android actions for android:configChanges="" which can trigger the onCreate in your Activity lifecycle.

    This is very important - The ones NOT Specified in the manifest are the ones that trigger your onCreate and The ones specified in the manifest are the ones that trigger your onConfigurationChanged method in your Activity Class.

    So you need to identify which config changes you need to handle yourself. For the Android Encyclopedically Challenged like me, I used the quick hints pop-out in Android Studio and added in almost every possible configuration option. Listing all of these basically said that I would handle everything and onCreate will never be called due to configurations.

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

    Now obviously I don't want to handle everything, so I began eliminating the above options one at a time. Re-building and testing my app after each removal.

    Another important point: If there is just one configuration option being handled automatically that triggers your onCreate (You do not have it listed in your manifest above), then it will appear like onConfigurationChanged is not working. You must put all relevant ones into your manifest.

    I ended up with 3 that were triggering onCreate originally, then I tested on an S10+ and I was still getting the onCreate, so I had to do my elimination exercise again and I also needed the |screenSize. So test on a selection of platforms.

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

    So my suggestion, although I'm sure someone can poke holes in this:

    1. Add your onConfigurationChanged method in your Activity Class with a TOAST or LOG so you can see when its working.

    2. Add all possible configuration options to your manifest.

    3. Confirm your onConfigurationChanged method is working by testing your app.

    4. Remove each config option from your manifest file one at a time, testing your app after each.

    5. Test on as large a variety of devices as possible.

    6. Do not copy/paste my snippet above to your manifest file. Android updates change the list, so use the pop-out Android Studio hints to make sure you get them all.

    I hope this saves someone some time.

    My onConfigurationChanged method just for info below. onConfigurationChanged is called in the lifecycle after the new orientation is available, but before the UI has been recreated. Hence my first if to check the orientation works correctly, and then the 2nd nested if to look at the visibility of my UI ImageView also works correctly.

        @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 讨论(0)
  • 2020-11-22 10:06

    I just want to propose another alternative that will concern some of you, indeed, as explained above:

    android:configChanges="orientation|keyboardHidden" 
    

    implies that we explicitly declare the layout to be injected.

    In case we want to keep the automatic injection thanks to the layout-land and layout folders. All you have to do is add it to the onCreate:

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

    Here, we display or not the actionbar depending on the orientation of the phone

    0 讨论(0)
提交回复
热议问题