安卓系统:配置更改未更新

4
我正在使用XML标签。
android:configChanges="orientation|keyboardHidden|keyboard"

以下代码用于检测设备方向变化并改变布局:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    disp = getWindowManager().getDefaultDisplay();
    swidth = disp.getWidth();
    sheight = disp.getHeight();
    parent.removeAllViews();
    parent = new RelativeLayout(this);
    if(newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)
        layoutPortrait();
    else
        layoutLandscape();
}

这在从纵向到横向时运作良好。但是,由于某种原因,从横向到纵向(从横向开始或切换到横向然后返回)不会将屏幕改回纵向。

通过使用日志消息,我已经确定在处于横向模式之后,Display和Configuration类不会更新。它们仍然保持与设备处于横向时相同的方向/长度/宽度值。

有人知道为什么吗?

附加代码(由贡献者请求)

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    disp = getWindowManager().getDefaultDisplay();
    swidth = disp.getWidth();
    sheight = disp.getHeight();
    int ornt;
    if(swidth == sheight)
        ornt = Configuration.ORIENTATION_SQUARE;
    else if(swidth < sheight)
        ornt = Configuration.ORIENTATION_PORTRAIT;
    else if(swidth > sheight)
        ornt = Configuration.ORIENTATION_LANDSCAPE;
    else
        ornt = Configuration.ORIENTATION_UNDEFINED;
    parent = new RelativeLayout(this);
    labelOne = new TextView(this);
    labelOne.setText("Temperature");
    labelOne.setId((int)(Math.random()*Integer.MAX_VALUE));
    temp = new EditText(this);
    temp.setSingleLine(true);
    temp.setBackgroundColor(Color.WHITE);
    temp.setTextColor(Color.BLACK);
    temp.setId((int)(Math.random()*Integer.MAX_VALUE));
    labelTwo = new TextView(this);
    labelTwo.setText("Humidity(%)");
    labelTwo.setId((int)(Math.random()*Integer.MAX_VALUE));
    humidity = new EditText(this);
    humidity.setSingleLine(true);
    humidity.setBackgroundColor(Color.WHITE);
    humidity.setTextColor(Color.BLACK);
    humidity.setId((int)(Math.random()*Integer.MAX_VALUE));
    output = new TextView(this);
    output.setBackgroundColor(Color.WHITE);
    output.setTextColor(Color.BLACK);
    output.setId((int)(Math.random()*Integer.MAX_VALUE));
    submit = new Button(this);
    submit.setText("Calculate");
    submit.setId((int)(Math.random()*Integer.MAX_VALUE));
    submit.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
              Double result = Calculate.calculate(getInputs());
              if(result !=null) {
                String answer = String.format("%,.1f",result);
                if(f.isChecked()) {
                    output.setText(answer + "°F");
                } else {
                    output.setText(answer + "°C");
                }
              }
        }
    });
    f = new RadioButton(this);
    f.setText("Fahrenheit");
    c = new RadioButton(this);
    c.setText("Celsius");
    rg = new RadioGroup(this);
    rg.setOnCheckedChangeListener(new ListenForMode());
    rg.addView(f);
    rg.addView(c);
    rg.setId((int)(Math.random()*Integer.MAX_VALUE));
    f.setChecked(true);
    if(ornt == Configuration.ORIENTATION_PORTRAIT || ornt == Configuration.ORIENTATION_SQUARE)
        layoutPortrait();
    else
        layoutLandscape();
}

最终更新

问题出现在模拟器对方向变化的响应不正确上。我更改了onConfigurationChanged(...)中的方向检查条件,使用宽度 < 高度判断为竖屏,其他情况判断为横屏。这在我的Android设备上完美运行。

感谢所有为此问题做出贡献的人!


为什么不让Android通过提供备用资源来处理布局的切换呢? - bschultz
同意。还有,你的layoutLandScape例程是否通过setRequestedOrientation调用了?一旦这样做,您将停止收到方向更改的通知。 - Lawrence D'Oliveiro
@LawrenceD'Oliveiro 不,它并没有调用那个方法。它只是重新绘制布局以适应横向视图。 - bgroenks
你的布局中没有回退调用。你应该将 if else if 重构为 if else。检查是否为纵向模式,如果不是,则忽略其余部分...(这不会解决你的问题,但应该更加健壮)。 - WarrenFaith
@bschultz 你所说的“替代资源”是指BMP GUI布局吗?我不知道如何制作它们,而且我更愿意尽可能地使用纯Java编写我的程序,因为那是我所熟悉和喜爱的。 - bgroenks
显示剩余2条评论
2个回答

1

你真的不应该在清单文件中覆盖configChanges。Android可以为你处理视图的重绘,而且它实际上处理得非常好,特别是如果你在资源文件夹中有过滤布局。

如果你因为AsyncTask失去了Context而覆盖configChanges(就像我曾经做过的那样),我建议使用IntentService来处理异步工作,因为Service不会与任何一个Activity绑定。


但是如果我想使用不同的布局,难道我不必覆盖它吗?请记住,我是在Java代码中完成这个过程,而不是使用BMP资源。 - bgroenks
如果您将横向布局放在layout-land中,并保持名称不变,Android将选择在layout-land中的布局。 - SeanPONeil
你是说你在Java代码中构建布局而不是XML吗? - SeanPONeil

0
如果在模拟器上发生这种情况,那么没关系——模拟器在配置更改方面的行为有点奇怪。我一直在尝试解决类似的问题,直到我注意到该应用在真实设备上运行良好。
看起来模拟器忽略了android:configChanges="orientation"属性,但是以一种有点奇怪的方式:它确实强制进行配置更改,但并不总是在应该调用onConfigurationChanged(..)方法的时候调用它。

它在模拟器上什么也不做。我有提到它在实际手机上会崩溃吗? - bgroenks

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