在Android中处理屏幕布局更改






4.80/5 (11投票s)
如何在Android中以编程方式处理屏幕方向变化。
引言
以编程方式处理屏幕布局、锁定屏幕布局、在设备布局更改时控制活动生命周期是每个Android开发者在开发应用程序时都会遇到的主题。在本文中,我简要分享了我关于以编程方式管理Android中屏幕布局的经验。每个部分都侧重于该主题的不同方面。
手动处理布局更改
第一个显而易见的讨论点是如何手动处理布局更改。当为活动手动处理布局更改时
- 设备布局更改时不会自动创建新的活动。通常情况下,布局更改后,当前活动会自动销毁(调用`onPause()`、`onStop()`和`onDestroy()`方法),并为新的布局创建一个新的活动(调用`onCreate()`、`onStart()`和`onResume()`方法)。
- 如有必要,应手动对新布局的GUI进行任何更改。
接下来,让我们考虑一下应该以编程方式执行哪些操作来手动处理布局更改。假设您的应用程序中有一个名为`InfoActivity`的活动,您将为此活动以编程方式处理布局更改。在您的`AndroidManifest.xml`中,您已经有一个类似于下面为`InfoActivity`的条目
<activity android:name=".InfoActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
第一步,您应该在`activity`标签内添加`android:configChanges`属性。
<activity android:name=".InfoActivity"
android:configChanges="orientation|keyboardHidden" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
这行代码告诉Android,每当设备布局更改或打开硬件键盘时,`InfoActivity`的实现都具有处理布局更改的逻辑。更多信息可在Android文档中找到。
接下来,需要实现手动处理此布局更改的逻辑。为此,您需要重写`InfoActivity`中的`onConfigurationChanged()`方法。
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
.
.
.
}
`AndroidManifest.xml`中的更改会阻止在设备屏幕布局更改时自动创建新的活动。如果需要对新布局的GUI进行任何更改,则应在重写的`onConfigurationChanged()`方法中手动处理。
注意!尽管这些更改阻止了每次屏幕布局更改时都创建新的活动,但它们并没有锁定布局。换句话说,您仍然会看到屏幕旋转。锁定屏幕布局将在本文后面解释。
何时手动处理布局更改?
接下来要考虑的问题是,何时手动处理屏幕布局更改?Android框架默认情况下会在屏幕布局更改时创建显示的活动。这总是必要的吗?如果不是,在哪些情况下是必要的?根据我的个人经验,对上述问题的答案是:当屏幕布局更改时,并不总是需要销毁显示的活动并为新的布局再次创建它。只有当纵向和横向布局本质上不同时,才需要这样做。让我们考虑两个简单的例子。
下面的第一个示例在列表视图中显示一周中的日期。在纵向和横向布局中,视图都是相同的。因此,每当屏幕布局更改时,都没有必要再次销毁和创建此活动。
<activity android:name=".Main"
android:configChanges="orientation|keyboardHidden" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
public class Main extends ListActivity {
private static final String[] MONTHS = new String[] {
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, MONTHS));
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// .
// Add code if needed
// .
}
}
第二个示例显示两张图像;在纵向布局中,它们垂直对齐,在横向布局中,它们水平对齐。
显然,布局本质上是不同的,并且每次屏幕布局更改时都需要再次创建相应的活动。在这种情况下,无法手动处理活动生命周期。
<activity android:name=".Main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
public class Main extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getResources().getConfiguration().orientation ==
Configuration.ORIENTATION_PORTRAIT) {
setContentView(R.layout.main_p);
} else {
setContentView(R.layout.main_l);
}
}
}
--------------
| main_p.xml |
--------------
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView android:src="@drawable/image1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:layout_marginLeft="60dip" />
<ImageView android:src="@drawable/image2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:layout_marginLeft="60dip" />
</LinearLayout>
--------------
| main_l.xml |
--------------
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView android:src="@drawable/image1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:layout_marginLeft="20dip" />
<ImageView android:src="@drawable/image2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:layout_marginLeft="40dip"/>
</LinearLayout>
锁定屏幕布局
以编程方式
以编程方式锁定屏幕布局需要特别告诉Android应该显示哪个屏幕布局。
如果您**没有**手动处理屏幕布局更改,则应在`onCreate()`方法的实现中执行此操作
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
// or = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
setRequestedOrientation(orientation);
.
// Add code if needed
.
}
如果您**正在**手动处理屏幕布局更改,则应在`onConfigurationChanged()`方法的实现中指定所需的屏幕布局
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
int orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
// or = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
setRequestedOrientation(orientation);
.
// Add code if needed
.
}
静态方式
或者,您也可以静态地锁定屏幕布局。这在`AndroidManifest.xml`中的`activity`标签中使用`android:screenOrientation`属性完成。
<activity android:name=".InfoActivity"
android:screenOrientation="portrait" >
.
.
.
</activity>
或
<activity android:name=".InfoActivity"
android:screenOrientation="landscape" >
.
.
.
</activity>
有关静态锁定屏幕布局的更多信息,请参阅Android文档。
相关
这项研究是在实现下面列出的两个Android应用程序期间完成的。我们邀请您检查一下这些Android应用程序中屏幕布局从纵向到横向以及反向更改的流畅程度。请点击应用程序名称从Google Play下载。
- BeSocial - 一个创新的应用程序,将社交网络和移动导航结合在一起。关注Twitter
- Weather-Buddy - 一款为旅行者和通勤者设计的创新型天气应用程序。关注Twitter