studio programacion herramientas fundamentos con avanzado aplicaciones android android-layout screen-orientation

programacion - manual de android en pdf



Android: Detectó la orientación cambiada (4)

Necesito detectar un cambio de orientación en mi aplicación, pero no quiero que mi diseño cambie de vertical a horizontal. Actualmente estoy usando OrientationEventListener sin embargo, detectar el ángulo de orientación no es suficiente. Quiero detectar que el usuario cambió de vertical a horizontal o viceversa, y eso no es solo detectar si el ángulo de orientación es 90 o 270.

Quiero hacer la misma detección que hace Android para cambiar la orientación de la actividad. Intenté anular onConfigurationChanged y onConfigurationChanged si la orientación es horizontal / vertical, sin embargo, esto todavía cambia el diseño de mi actividad a horizontal.

¿Hay alguna forma de usar onConfigurationChanged pero obliga a que el diseño permanezca en vertical?
¿Hay otra manera de detectar el cambio de OrientationEventListener sin usar OrientationEventListener ? En última instancia, puedo implementar mi propio algoritmo de orientación cambiado, ¿alguna idea sobre esto? Tiene que ser algo más complejo que if(90-THRESHOLD <= orientation <= 90+THRESHOLD) , quiero detectar si el usuario realizó el movimiento completo Retrato-> Paisaje u Paisaje-> Retrato.

Gracias por la ayuda,
Filipe


Creé la siguiente clase para detectar cambios de orientación, manteniendo la orientación original de mi actividad:

public class SensorOrientationChangeNotifier { public final String TAG = getClass().getSimpleName(); private ArrayList<WeakReference<SensorOrientationChangeNotifier.Listener>> mListeners = new ArrayList<WeakReference<SensorOrientationChangeNotifier.Listener>>(3); private int mOrientation = 0; private SensorEventListener mSensorEventListener; private SensorManager mSensorManager; private static SensorOrientationChangeNotifier mInstance; public static SensorOrientationChangeNotifier getInstance() { if (mInstance == null) mInstance = new SensorOrientationChangeNotifier(); return mInstance; } private SensorOrientationChangeNotifier() { mSensorEventListener = new NotifierSensorEventListener(); Context applicationContext = GlobalData.getInstance().getContext(); mSensorManager = (SensorManager) applicationContext.getSystemService(Context.SENSOR_SERVICE); } /** * Call on activity reset() */ private void onResume() { mSensorManager.registerListener(mSensorEventListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); } /** * Call on activity onPause() */ private void onPause() { mSensorManager.unregisterListener(mSensorEventListener); } private class NotifierSensorEventListener implements SensorEventListener { @Override public void onSensorChanged(SensorEvent event) { float x = event.values[0]; float y = event.values[1]; int newOrientation = mOrientation; if (x < 5 && x > -5 && y > 5) newOrientation = 0; else if (x < -5 && y < 5 && y > -5) newOrientation = 90; else if (x < 5 && x > -5 && y < -5) newOrientation = 180; else if (x > 5 && y < 5 && y > -5) newOrientation = 270; //Log.e(TAG,"mOrientation="+mOrientation+" ["+event.values[0]+","+event.values[1]+","+event.values[2]+"]"); if (mOrientation != newOrientation){ mOrientation = newOrientation; notifyListeners(); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } } public int getOrientation() { return mOrientation; } public interface Listener { void onOrientationChange(int orientation); } public void addListener(SensorOrientationChangeNotifier.Listener listener) { if (get(listener) == null) // prevent duplications mListeners.add(new WeakReference<SensorOrientationChangeNotifier.Listener>(listener)); if (mListeners.size() == 1) { onResume(); // this is the first client } } public void remove(SensorOrientationChangeNotifier.Listener listener) { WeakReference<SensorOrientationChangeNotifier.Listener> listenerWR = get(listener); remove(listenerWR); } private void remove(WeakReference<SensorOrientationChangeNotifier.Listener> listenerWR) { if (listenerWR != null) mListeners.remove(listenerWR); if (mListeners.size() == 0) { onPause(); } } private WeakReference<SensorOrientationChangeNotifier.Listener> get(SensorOrientationChangeNotifier.Listener listener) { for (WeakReference<SensorOrientationChangeNotifier.Listener> existingListener : mListeners) if (existingListener.get() == listener) return existingListener; return null; } private void notifyListeners() { ArrayList<WeakReference<SensorOrientationChangeNotifier.Listener>> deadLiksArr = new ArrayList<WeakReference<SensorOrientationChangeNotifier.Listener>>(); for (WeakReference<SensorOrientationChangeNotifier.Listener> wr : mListeners) { if (wr.get() == null) deadLiksArr.add(wr); else wr.get().onOrientationChange(mOrientation); } // remove dead references for (WeakReference<SensorOrientationChangeNotifier.Listener> wr : deadLiksArr) { mListeners.remove(wr); } } public boolean isPortrait(){ return mOrientation == 0 || mOrientation == 180; } public boolean isLandscape(){ return !isPortrait(); } }

Úsalo de la siguiente manera:

En AndroidManifest.xml -

<activity ... android:screenOrientation="portrait" >

En tu actividad:

public class MainActivity extends Activity implements SensorOrientationChangeNotifier.Listener { @Override protected void onResume() { super.onResume(); SensorOrientationChangeNotifier.getInstance().addListener(this); } @Override protected void onPause() { super.onPause(); SensorOrientationChangeNotifier.getInstance().remove(this); } @Override public void onOrientationChange(int orientation) { if (orientation == 90 || orientation == 270){ // Do some landscape stuff } else { // Do some portrait stuff } } } }


Hola, screamingnoises, ¿esto es lo que estás buscando?

// Set background image, rotatable View view = getWindow().getDecorView(); int orientation = getResources().getConfiguration().orientation; if (Configuration.ORIENTATION_LANDSCAPE == orientation) { //Do SomeThing; // Landscape } else { //Do SomeThing; // Portrait }


Ok, después de intentar usar la API de Android y no poder hacer lo que necesito, implementé mi propio algoritmo y en realidad no fue tan complicado: usé un OrientationEventListener, y calculé si la orientación está en los 4 puntos de orientación ( en mi código solo detecto LANDSCAPE_RIGHT y PORTRAIT_UP :

orientationListener = new OrientationEventListener(context, SensorManager.SENSOR_DELAY_UI) { public void onOrientationChanged(int orientation) { if(canShow(orientation)){ show(); } else if(canDismiss(orientation)){ dismiss(); } } }; @Override public void onResume(){ super.onResume(); orientationListener.enable(); } @Override public void onPause(){ super.onPause(); orientationListener.disable(); } private boolean isLandscape(int orientation){ return orientation >= (90 - THRESHOLD) && orientation <= (90 + THRESHOLD); } private boolean isPortrait(int orientation){ return (orientation >= (360 - THRESHOLD) && orientation <= 360) || (orientation >= 0 && orientation <= THRESHOLD); } public boolean canShow(int orientation){ return !visible && isLandscape(orientation); } public boolean canDismiss(int orientation){ return visible && !dismissing && isPortrait(orientation); }


Para detectar la orientación, le pediremos a la actividad que nos proporcione el ancho y la altura de la actividad, para que podamos encontrar si Ancho> Altura que será "Paisaje" o la Altura opuesta> ancho que es "Retrato" - El siguiente Código es Probado y funcionando.

@SuppressWarnings("deprecation") public void detectScreenOrientation(){ WindowManager wm = getWindowManager(); Display d = wm.getDefaultDisplay(); if (d.getWidth() > d.getHeight()){ Log.d("Orientation","Landscape mode"); } else { Log.d("Orientation", "Portrait mode"); } }