我想在设备从纵向旋转到横向时do_something()
。
我在清单中添加了<activity android:configChanges="orientation" >
。因此,每当我旋转设备时,都会调用onConfigurationChanged()
。它将不重新创建活动。
在我的onConfigurationChanged()
函数中:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
do_something();
}
then_fire_off_the_screen_rotation_as_normal();
// which means re-start the Activity
// i expect it will fire off onSaveInstanceState() -> onPause() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume()
}
我的问题是,我不知道我能在then_fire_off_the_screen_rotation_as_normal()
做些什么。
我尝试使用setRequestedOrientation()
,但似乎不是为此目的服务的功能:
当我传入ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
,ActivityInfo.SCREEN_ORIENTATION_SENSOR
或ActivityInfo.SCREEN_ORIENTATION_USER
时,活动仍然不重新启动。 (就像不打电话一样。)
当我进入ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
时,方向传感器关闭。 (正如它所说的那样。)
当我通过ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
时,活动强制关闭 AndroidRuntime:NullPointerException
。
(具体:这是因为在纵向布局中以编程方式添加了片段,但在横向布局中没有。在do_something()
函数中,我将删除这些片段,因为它们不是必需的在横向模式下。)
答案 0 :(得分:3)
嗯,我想这种简单的方式可以满足我的需求:
不添加<activity android:configChanges="orientation" >
。意味着不需要覆盖onConfigurationChanged()
。
在onSaveInstanceState()
:
@Override
protected void onSaveInstanceState(Bundle outState) {
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
do_something();
}
super.onSaveInstanceState(outState);
}
*在 do_something()
之前,请务必super.onSaveInstanceState()
。
(因为在我的情况下,我从布局和活动中删除碎片。如果它在super.onSaveInstanceState()
之后,布局将已经保存到Bundle中。然后碎片将<在活动重新创建后重新创建strong> 。###)
###我已经证明了这一现象。但What to determine a Fragment restore upon Activity re-create?的原因仅仅是我的猜测。如果您对此有任何想法,请回答my another question。谢谢!
嗯,进一步改进上述方法,解决了第一条评论中提出的问题:(仍然很简单)
@Override
protected void onSaveInstanceState(Bundle outState) {
if (isPortrait2Landscape()) {
do_something();
}
super.onSaveInstanceState(outState);
}
private boolean isPortrait2Landscape() {
return isDevicePortrait() && (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE);
}
和isDevicePortrait()
就像:
private boolean isDevicePortrait() {
return (findViewById(R.id.A_View_Only_In_Portrait) != null);
}
*请注意,我们 无法 使用getResources().getConfiguration().orientation
来确定设备当前是字面纵向。这是因为Resources
对象在屏幕旋转后更改 RIGHT AFTER - 以前 {{ 1}}被称为!!
如果您不想使用onSaveInstanceState()
来测试方向(由于任何原因,并且它不是那么整洁),请保留一个全局变量findViewById()
并将其初始化为private int current_orientation;
in current_orientation = getResources().getConfiguration().orientation;
。这似乎更整洁。但我们应该注意 不要 在活动生命周期中的任何地方进行更改。
答案 1 :(得分:1)
// which means re-start the Activity
// i expect it will fire off onSaveInstanceState() -> onPause() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume()
onPause(),onStop()等会触发的这种假设是不正确的。通过使用onConfigurationChanged
,您告诉Android不要执行这些步骤,而是您将处理临时变量中布局信息的保存,然后调用InitializeUI()
,然后将布局设置回您的方式想。我将发布一个类似的东西的例子,并在一瞬间为我工作。
编辑:这是示例
@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
setContentView(R.layout.main);
Log.i("configChange", "configChange");
String tmp = connect.getText().toString();
boolean onTmp = on.isEnabled();
boolean offTmp = off.isEnabled();
boolean connTmp = reconnect.isEnabled();
InitializeUI();
connect.setText(tmp);
on.setEnabled(onTmp);
off.setEnabled(offTmp);
reconnect.setEnabled(connTmp);
}
现在我的InitializeUI()
方法只不过是一堆findViewById并且正在设置onClickListeners。还要确保调用InitializeUI() in your
onCreate()`。
希望这会有所帮助。