Android 不同的布局;“景观”;及;横向反转“;方向 我的问题是:

Android 不同的布局;“景观”;及;横向反转“;方向 我的问题是:,android,orientation,landscape,device-orientation,orientation-changes,Android,Orientation,Landscape,Device Orientation,Orientation Changes,对于某些要求,我的活动需要两种不同的xml布局: 一个用于横向模式 另一个用于横向反转模式(横向反转) 不幸的是,Android不允许为横向反转创建单独的布局(就像我们可以使用布局区域和布局端口为纵向和横向创建布局一样) 好的,唯一的方法是从java代码中更改活动xml 我所尝试的: 1) 覆盖onConfigurationChanged()方法以检测方向变化,但我无法确定是横向还是横向反转: @Override public void onConfigurationChanged(Conf

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

  • 一个用于横向模式
  • 另一个用于横向反转模式(横向反转)
不幸的是,Android不允许为横向反转创建单独的布局(就像我们可以使用
布局区域
布局端口
为纵向和横向创建布局一样)

好的,唯一的方法是从java代码中更改活动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) 按照中的建议,将
OrientationEventListener
SENSOR\u DELAY\u 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);
                }

            }};
我的问题: 在
“横向”
“横向反转”
方向之间更改活动布局是否有更好的解决方案

非常感谢您的任何建议。

您是否正在尝试作为?。您可以使用活动属性
sensorscape

已编辑:尝试按此处所述使用Display.getOrientation

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

所以,似乎唯一的方法就是尽可能多地听SensorManager的讲话

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

为了实现这一目标,您需要实现一个旋转侦听器, 您还需要知道,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();
}

最后一步:享受

谢谢你的回答。我刚试过你的建议,但没用。皮特的回答完全错了--1) 使用
android:screenOrientation
属性,您不能使用
|
--2) 与或其他常量无关。因为
Configuration.orientation
的值为1或=2(或),而
ActivityInfo
的常量的值为0、1、8和9。好的,你是否遇到过Dan Morrill的主题->问题是,设备如何告诉你它已被重新定向?答案是:android.view.Display.getRotation()。该方法将返回四个值中的一个,指示设备未重新定向(旋转0),或已重新定向90度、180度或270度(分别为旋转90度、旋转180度和旋转270度)。使用
getRotation()
将返回正确的值。但问题是在哪里使用它?我在
onConfigurationChanged()
方法中添加了一个
getRotation()
的切换案例,当您进行90°旋转时效果很好,但是对于180°旋转
onConfigurationChanged()
不会被调用,因为屏幕大小没有从land到land rev(或port到port rev)进行更改。我知道,但事实并非如此(至少在我的三星S3、Nexus7、Nexus10和宏碁iconia中是如此)。顺便说一句,尝试用一个活动创建一个简单的项目,然后在onCreate方法中添加一个断点(或一些日志),然后快速旋转180度(从纵向到纵向或从陆地到陆地),您将看到onCreate()方法并不总是被调用。我认为android认为从模式切换到反向模式不会影响大小,因此无需重新创建活动或调用onConfigurationChanged()。或者这只是一个安卓bug。