Android: определение ориентации изменено - PullRequest
19 голосов
/ 23 ноября 2011

Мне нужно обнаружить изменение ориентации в моем приложении, но я не хочу, чтобы моя компоновка изменялась с книжной на альбомную.В настоящее время я использую OrientationEventListener, но определения угла ориентации недостаточно.Я хочу обнаружить, что пользователь изменил с портретного на ландшафтный или наоборот, и это не просто обнаружение, если угол ориентации равен 90 или 270.

Я хочу сделать то же обнаружение, что и Android, чтобы изменитьориентация деятельности.Я попытался переопределить onConfigurationChanged и проверить, является ли ориентация альбомной / портретной, однако это по-прежнему меняет макет моей деятельности на альбомную.

Есть ли способ использовать onConfigurationChanged, но заставить макет оставаться в портретной ориентации?Есть ли другой способ обнаружить изменение ориентации без использования OrientationEventListener.В конечном итоге я могу реализовать свой собственный алгоритм изменения ориентации, есть идеи на этот счет?Это должно быть что-то более сложное, чем if(90-THRESHOLD <= orientation <= 90+THRESHOLD), я хочу определить, сделал ли пользователь полное движение Портрет-> Пейзаж или Пейзаж-> Портрет.

Спасибо за помощь,
Filipe

Ответы [ 4 ]

33 голосов
/ 24 ноября 2011

Хорошо, после попытки использовать API Android и неспособности сделать то, что мне нужно, я реализовал свой собственный алгоритм, и на самом деле все было не так сложно: я использовал OrientationEventListener и рассчитал, если ориентацияточки ориентации (в моем коде я обнаруживаю только LANDSCAPE_RIGHT и 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);
}
9 голосов
/ 24 ноября 2011

Привет, крики, это то, что ты ищешь?

// 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
    } 
3 голосов
/ 26 октября 2016

Я создал следующий класс для определения изменений ориентации, сохраняя исходную ориентацию своей деятельности:

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

Используйте его следующим образом:

В AndroidManifest.xml -

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

В вашей деятельности:

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
                 }
        }
    }
}
0 голосов
/ 08 мая 2014

Чтобы определить ориентацию, мы попросим, ​​чтобы действие предоставило нам ширину и высоту действия, таким образом, мы можем найти, если Ширина> Высота, которая будет "Пейзаж" или противоположная Высота> ширина, которая "Портрет" -Следующий код проверен и работает.

@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");
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...