“风景”和“横向反转”方向的不同布局

时间:2016-01-11 19:36:29

标签: android orientation landscape device-orientation orientation-changes

我的问题:

对于某些要求,我的活动需要两种不同的xml布局:

  • 一个用于横向模式。
  • 另一个用于横向反转模式(横向颠倒)。

不幸的是,Android不允许为横向反转创建单独的布局(就像我们可以使用layout-landlayout-port来处理纵向和横向布局)。

AFAIK,唯一的方法是从java代码更改activity-xml。

我尝试了什么:

1)覆盖onConfigurationChanged()方法以检测方向变化,但我无法弄清楚它是横向还是横向反转:

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

     if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
         Log.d("TEST","Landscape");
     }

}

(清单中我的活动代码中的android:configChanges="keyboardHidden|orientation|screenSize|layoutDirection"

2)根据this answer中的建议使用OrientationEventListenerSENSOR_DELAY_NORMAL,但在输入if块之前设备方向会发生变化,因此我看到了视图的延迟更新:

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

            }};

我的问题:

是否有更好的解决方案来更改"Landscape""Landscape-reverse"方向之间的活动布局?

非常感谢任何建议。

2 个答案:

答案 0 :(得分:5)

您是否正在尝试suggested here?您可以使用活动属性sensorLandscape

处理具有不同类型的配置反向和标准的事件

已编辑:尝试使用此处所述的Display.getOrientation http://android-developers.blogspot.in/2010/09/one-screen-turn-deserves-another.html

并且不要忘记在清单中的活动上设置configChanges标记,以便在onConfigurationChanges()中手动处理更改。

因此,似乎只有这样才能尽可能频繁地收听SensorManager。

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

答案 1 :(得分:0)

为了实现这一目标,您需要实现一个旋转侦听器, 你还需要知道android破坏对象并重新创建它们 根据配置限定符加载布局,值......

步骤01:创建Java接口[rotationCallbackFn]

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

步骤02:创建Java类[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;
}

}

步骤03:将这些语句添加到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();
}

最后一步:享受