安卓屏幕方向

20

我尝试使用 getOrientation() 方法获取方向值,但它总是返回 0!


7
请先尝试旋转设备。 - noelicus
由于问题(尤其是答案)涉及方向作为一般问题,而不是特定方法,因此撤销了第三方标题编辑。 - Chris Stratton
8个回答

46

getOrientation()已经被废弃,但这并不一定是您问题的根源。确实,您应该使用getRotation()而不是getOrientation(),但只有在针对Android 2.2(API级别8)或更高版本时才能使用它。有些人甚至包括谷歌员工有时都会忘记这一点。

例如,在我运行Android 2.2的HTC Desire上,getOrientation()getRotation()报告的值相同:

  • 0(默认,竖屏),
  • 1(设备逆时针旋转90度),
  • 3(设备顺时针旋转90度)

当你把它“倒过来”时(旋转180度,该值为2),它不会报告。这个结果可能是设备特定的。

首先,你应该明确你使用的是模拟器还是真机。你知道如何旋转模拟器吗?然后我建议创建一个带有onCreate()方法的小测试程序,就像这样:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    WindowManager mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    Display mDisplay = mWindowManager.getDefaultDisplay();

    Log.d("ORIENTATION_TEST", "getOrientation(): " + mDisplay.getOrientation());

}

检查您的设备屏幕是否已经在设备设置中被锁定 设置 > 显示 > 自动旋转屏幕。如果该复选框未被选中,Android 将不会向您的 Activity 报告方向更改。需要明确的是:它不会重新启动该活动。在我的情况下,我只得到了0,就像你所描述的那样。

如果您在 onCreate() 中添加这些行,您可以从您的程序中检查这一点。

int sysAutoRotate = 0;
try {
        sysAutoRotate = Settings.System.getInt(getContentResolver(), Settings.System.ACCELEROMETER_ROTATION);
    } catch (SettingNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
Log.d("ORIENTATION_TEST", "Auto-rotate Screen from Device Settings:" + sysAutoRotate);

如果自动旋转关闭,则它将返回0,如果自动旋转打开,则返回1。 另一种尝试。在您的原始程序中,您可能已经在清单中设置了

android:screenOrientation="portrait"

同样的效果,但这次只针对您的活动。如果您制作了小型测试程序,这种可能性就会被消除(这就是我推荐它的原因)。

注意:是的,整个方向/旋转主题确实是一个“有趣”的主题。尝试各种方法,使用Log.d(),实验,学习。


37

如果您想知道当前显示的内容是否处于横向模式或纵向模式(可能完全独立于手机的物理旋转),您可以使用:

getResources().getConfiguration().orientation

开发人员文档

public int orientation
自从: API Level 1

屏幕的总体方向。可能为ORIENTATION_LANDSCAPE、ORIENTATION_PORTRAIT或ORIENTATION_SQUARE中的一个。


在你需要支持旧的操作系统版本时,这是一个很好的解决方案。似乎比 getOrientation() 更可靠。 - dvs
到目前为止,这是唯一一个对我有效的解决方案! - AC2MO
似乎如果我在加载活动后没有旋转屏幕,getOrientation()总是返回ORIENTATION_UNDEFINED。这种方式避免了这个问题。 - Keith

5

有什么想法为什么getOrientation被弃用了?据我所知,getRotation做的事情完全一样。 - Edward Falk
1
如果您必须支持API 7,则无法使用getRotation,它是从API 8开始的。 - mxcl

4
为了避免使用过时的方法,请使用Android Configuration类,该类位于这里。它从API级别1开始就可用,并在最新的Android设备上仍然可用(未被弃用)。
例如,请考虑以下代码片段:
Configuration config = getResources().getConfiguration();
if (config.orientation == Configuration.ORIENTATION_PORTRAIT)
{
    setContentView(R.layout.portraitStart);
}
else
{
    setContentView(R.layout.landscapeStart);
}

祝你好运 - 希望这个答案能帮助遇到它的人。


1
为什么要通过代码手动切换?布局配置就是为此而存在的。/res/layout 和 /res/layout-land。 - afollestad

3

如何获取更详细的方向,例如横向左/右? - Mark13426

1
/* First, get the Display from the WindowManager */
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

/* Now we can retrieve all display-related infos */
int width = display.getWidth();
int height = display.getHeight();
int orientation = display.getOrientation();

1

我认为你需要创建两个不同的布局,并在不同的方向上填充不同的布局。我给你一个示例代码,对我来说运行良好。 "context"是您可以在自定义适配器中从活动中传递的参数。 如果您正在使用自定义适配器,则可以尝试此代码:

@Override
public View getView(final int position,
                    View convertView,
                    ViewGroup parent)
{
    View rowView = convertView;
    ViewHolder holder = null;
    int i = context.getResources().getConfiguration().orientation;

    if (rowView == null) {
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (i == Configuration.ORIENTATION_PORTRAIT) {
            rowView = inflater.inflate(R.layout.protrait_layout, null, false);
        } else {
            rowView = inflater.inflate(R.layout.landscape_layout, null, false);
        }

        holder = new ViewHolder();
        holder.button = (Button) rowView.findViewById(R.id.button1);
        rowView.setTag(holder);

    } else {
        holder = (ViewHolder) rowView.getTag();
    }
    return rowView;
}

否則,你可以直接在代碼中設置兩個不同的佈局。
    int i = context.getResources().getConfiguration().orientation;

        if (i == Configuration.ORIENTATION_PORTRAIT) {
                    ArrayAdapter<String> adt = new ArrayAdapter<String>(getApplicationContext(), R.layout.protrait_layout, name);
        } else {
                    ArrayAdapter<String> adt = new ArrayAdapter<String>(getApplicationContext(), R.layout.landscape_layout, name);
        }

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接