Different layout orientation "Landscape" and "Landscape-reverse"

My problem:

For some requirements, I need two different xml layouts for my activity:

  • One for Landscape mode.
  • And one more for the landscape-reverse mode (inverted landscape).

Unfortunately, Android does not allow creating a separate layout for landscape reverse (as we can do for portrait and landscape orientation with layout-land and layout-port ).

AFAIK, the only way is to change action-xml from java code.

What I tried:

1) Override the onConfigurationChanged() method to determine orientation changes, but I cannot figure out if it is Landscape or Landscape-reverse:

 @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { Log.d("TEST","Landscape"); } } 

(Whith android:configChanges="keyboardHidden|orientation|screenSize|layoutDirection" in the activity tag in the manifest)

2) Use OrientationEventListener with SENSOR_DELAY_NORMAL as suggested in this answer , but the device orientation changes before entering my if blocks, so I get a deferred view update:

 mOrientationEventListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL){ @Override public void onOrientationChanged(int orientation) { if (orientation==0){ Log.e("TEST", "orientation-Portrait = "+orientation); } else if (orientation==90){ Log.e("TEST", "orientation-Landscape = "+orientation); } else if(orientation==180){ Log.e("TEST", "orientation-Portrait-rev = "+orientation); }else if (orientation==270){ Log.e("TEST", "orientation-Landscape-rev = "+orientation); } else if (orientation==360){ Log.e("TEST", "orientation-Portrait= "+orientation); } }}; 

My question is:

Is there a better solution for changing the type of activity between "Landscape" and "Landscape-reverse" orientation?

Any suggestions are welcome.

+5
source share
2 answers

Are you trying to use here ? You can handle the event with different types of configuration in the reverse order and standardly using the sensorLandscape activity sensorLandscape

EDITED: try using Display.getOrientation as described here http://android-developers.blogspot.in/2010/09/one-screen-turn-deserves-another.html

And don't forget to set the configChanges flag for activity in the manifest in order to process the changes manually in onConfigurationChanges() .

Thus, it seems that the only way to do this is to listen to the SensorManager as often as possible.

 SensorManager sensorMan = (SensorManager)getSystemService(SENSOR_SERVICE); Sensor sensor = sensorMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); sensorMan.registerListener(...) 
+5
source

to achieve this, you need to implement a rotation receiver, you also need to know that android destroys objects and recreates them to load layouts, values ​​... based on configuration specifiers

STEP 01: create the Java interface [rotationCallbackFn]

  public interface rotationCallbackFn { void onRotationChanged(int lastRotation, int newRotation); } 

STEP 02: create the Java class [rotationListenerHelper]

 import android.content.Context; import android.hardware.SensorManager; import android.view.OrientationEventListener; import android.view.WindowManager; public class rotationListenerHelper { private int lastRotation; private WindowManager windowManager; private OrientationEventListener orientationEventListener; private rotationCallbackFn callback; public rotationListenerHelper() { } public void listen(Context context, rotationCallbackFn callback) { // registering the listening only once. stop(); context = context.getApplicationContext(); this.callback = callback; this.windowManager = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); this.orientationEventListener = new OrientationEventListener(context, SensorManager.SENSOR_DELAY_NORMAL) { @Override public void onOrientationChanged(int orientation) { WindowManager localWindowManager = windowManager; rotationCallbackFn localCallback = rotationListenerHelper.this.callback; if(windowManager != null && localCallback != null) { int newRotation = localWindowManager.getDefaultDisplay().getRotation(); if (newRotation != lastRotation) { localCallback.onRotationChanged(lastRotation, newRotation); lastRotation = newRotation; } } } }; this.orientationEventListener.enable(); lastRotation = windowManager.getDefaultDisplay().getRotation(); } public void stop() { if(this.orientationEventListener != null) { this.orientationEventListener.disable(); } this.orientationEventListener = null; this.windowManager = null; this.callback = null; } 

}

STEP 03: add these statements to your mainActivity

 // declaration private rotationListenerHelper rotationListener = null; private Context mContext; //... /* constructor ----------------------------------------------------------------*/ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContext = this; final int curOrientation = getWindowManager().getDefaultDisplay().getRotation(); switch (curOrientation) { case 0: //. SCREEN_ORIENTATION_PORTRAIT setContentView(R.layout.your_layout_port); break; //---------------------------------------- case 2: //. SCREEN_ORIENTATION_REVERSE_PORTRAIT setContentView(R.layout.your_layout_port_rev); break; //---------------------------------------- case 1: //. SCREEN_ORIENTATION_LANDSCAPE setContentView(R.layout.your_layout_land); break; //---------------------------------------- case 3: //. SCREEN_ORIENTATION_REVERSE_LANDSCAPE setContentView(R.layout.your_layout_land_rev); break; //---------------------------------------- } /*endSwitch*/ rotationListener = new rotationListenerHelper(); rotationListener.listen(mContext, rotationCB); //... } private rotationCallbackFn rotationCB = new rotationCallbackFn() { @Override public void onRotationChanged(int lastRotation, int newRotation) { Log.d(TAG, "onRotationChanged: last " + (lastRotation) +" new " + (newRotation)); /** * no need to recreate activity if screen rotate from portrait to landscape * android do the job in order to reload resources */ if ( (lastRotation == 0 && newRotation == 2) || (lastRotation == 2 && newRotation == 0) || (lastRotation == 1 && newRotation == 3) || (lastRotation == 3 && newRotation == 1) ) ((Activity) mContext).recreate(); } }; /* destructor -----------------------------------------------------------------*/ @Override protected void onDestroy() { rotationListener.stop(); rotationListener = null; Log.i(TAG, "onDestroy: activity destroyed"); super.onDestroy(); } 

FINAL STEP: ENJOY

0
source

Source: https://habr.com/ru/post/1240379/


All Articles