第一部分:开发前的准备-第五章 平板与手机

第5章 平板与手机

虽然理论上建议大家支持所有的屏幕设备,但这确实比较麻烦而且很容易出错。我们一般最好把手机和平板分时两大类来发布两个APK这样的效果更容易管理。读者可以理解为我们需要针对个别boss,换个职业来对付它。

5.1 平板与手机支持

其实我们发现平板提供更多的空间,让你的应用能显示更多的信息,但在手机上时可以会分几个部分显示,不会一次性全部显示出来。大部分情况下平板和手机的体验会有明显的不同。在android3.0上 ,android 引入了一套新的框架API,它允许我们更有效的设计应用,并更好的利用大屏幕。例如3.0新加入的Fragment类,这个类允许你对不同行为的UI组件分成独立的部分。然后你可以创建多屏设备(例如2屏,3屏手机)的布局啦并使它们结合起来。android3.0还导入了ActionBar这个类,它在屏幕上方提供一个专门的用户界面,来识别应用并提供用户操作和导航。 

本章内容以Fragment和ActionBar为例,在手机和平板上这两种设备上,它帮助你创建一个有着独特用户体验的应用程序,并且使用fragments和action bar。请记住看这一章之前,请看完前面的内容,它对你理解本章内容有重要的作用。本章描述了一个用户界面,它支持不同的屏幕尺寸和密度并有灵活的布局和可供选择的位图。

基本设计原则

下面是一些设计原则它能帮助你创建一个在手机和平板中都能适用的应用,并且优化用户体验。

1.基于fragments ,建立我们的activity:可重复使用的不同组合----多面板平板和单面板手机。在一个Acivity中一个 Fragment 代表一个行为或者一部分用户界面。你可以认为

Fragment是一个Activity中的一种模块。有其自己的生命周期,并可以在其中添加或删除而正在运行的Activity。如果你没有用过fragments,没关系,我们会在android 框架学习中的第一

章讲解,而且还有SDK中的例子。

2.使用ActionBar:它可以根据屏幕上的大小调整动作条的布局。

ActionBar是一个UI组件,它可以替代传统的title bar(是一种目前经常用的通知栏)。默认的 action bar 在上方的左边显示我们的应用 logo,然后是标题。右侧则是可以访问的选择菜单。你可以从选项菜单打开一个items(items可以理解为list或菜单中的一个项目)并直接打开它。你也能添加有导航功能的action bar作为标签或者下拉列表。直接点击icon还会导航到home页或者相当于一个back键的功能。

3.实现灵活布局:一个灵活的布局设计允许你的应用能使用屏幕大小的变化。不是所有的平板和手机都是一样的大小。你要根据平板和手机提供不同的fragment 组合,因为对于灵活调整布局有很重要的作用。

注意: 请使用android3.0版本才有可用的API哦!

 

5.2 只支持手机 

因为系统通常会自动缩放来使我们的资源或者布局来适应大屏幕,所以我们不需要过滤大屏幕。只要我们知道实践中应该注意哪些(第五章的内容)问题,我们的应用在大屏幕上也能很好的显示。

但你可能发现你的应用不会完全的等比缩放,或者可能你决定只为你的应用配置两个不同的屏幕适配版本。这种情况下,你可以使用<compatible-screens>节点来组合管理屏幕的密度和大

小。比如在Android Market就使用这样的信息来过滤你的应用,仅支持你应用配置的设备才会被显示出来。<compatible-screens> 节点必须包含一个或更多的<screen>节点,每一个<screen>节点中指定一个屏幕配置来兼容我们的应用。我们需要使用使用android:screenSize和

android:screenDensity这两个属性。每一个 <screen> 节点中必须包含两个属性来指定个别的屏幕配置,如果只有一个属性,那么这个节点是无效的。例如,如果你的应用兼容small和normal大小的屏幕 , 包括所有屏幕密度的话。你就必须指定8个 <screen> 节点,因为每一个屏幕大小中都有四种密度配置。你必须写出来,下面是在manifest中的实例代码:

 

<manifest ... >

    <compatible-screens>

        <!-- all small size screens -->

        <screenandroid:screenSize="small"android:screenDensity="ldpi"/>

        <screenandroid:screenSize="small"android:screenDensity="mdpi"/>

        <screenandroid:screenSize="small"android:screenDensity="hdpi"/>

        <screenandroid:screenSize="small"android:screenDensity="xhdpi"/>

        <!-- all normal size screens -->

        <screenandroid:screenSize="normal"android:screenDensity="ldpi"/>

        <screenandroid:screenSize="normal"android:screenDensity="mdpi"/>

        <screenandroid:screenSize="normal"android:screenDensity="hdpi"/>

        <screenandroid:screenSize="normal"android:screenDensity="xhdpi"/>

    </compatible-screens>

    ...

    <application ... >

        ...

    <application>

</manifest>

 

 

 

5.3 只支持平板 

如果让我们应用支持平板的话,我们可以完全放弃small屏幕的支持和优化。并在<supports-screens>节点中阻止小屏幕的设备在market上下载我们的应用

实例代码如下:

<manifest ... >

    <supports-screens 

                      android:smallScreens="false"

                      android:normalScreens="false"

                      android:largeScreens="true"

                      android:xlargeScreens="true"

                      android:requiresSmallestWidthDp="600"/>

    ...

    <application ... >

        ...

    </application>

</manifest>

 

 

需要同时使用两种方法描述关于屏幕大小的支持:

声明不支持small 和normal的屏幕大小。

声明需求一个最小化可用的屏幕宽度至少为600dp。

第一种方法执行与android3.1或者更老的版本,因为这些设备是基于四种传统的屏幕大小后缀。而第二种方法requiresSmallestWidthDp属性是为支持android3.2和更高的版本,因为这是新版本的特性。

为了支持requiresSmallestWidthDp 你可能需要在android 3.2或者更高的android版本中编译它们。但在老版本中是没有这个属性的,它们会在编译时报错。所以我们在新建工程的时候要选android3.2为开发版本,并在manifest中使用minSdkVersion指定最小的SDK版本。这样的话比3.2还老的版本就会忽略那个属性,所以就不会有运行时失败的风险。

警告: 如果使用 <supports-screens> 节点并设置large 屏幕的属性为false的话,那Android Market不会过滤large屏幕。你的应用仍然可以被large屏幕的设备安装,但执行时他不会适应屏幕。系统会模拟手机屏幕来显示。如果你想要阻止应用被large屏幕的设备下载。请使用上面关于手机的<compatible-screens>节点。所以我们最好结合<compatible-screens>和<supports-screens>。

5.4 屏幕兼容模式

首先我们看一下兼容模式的截图,图5-1使用了兼容模式,而图5-2没有使用兼容模式

 

图5-1 在android3.2平板上用兼容模式运行的一个应用

 

图5-2 和图5-1同样的应用,但兼容模式关闭掉了

注意: 如果你已经开发了一个android3.0版的应用,但它可能会为更大的屏幕(例如平板)调整布局,为了最好的用户体验,你应该关闭兼容模式。

屏幕兼容模式是不能在大屏幕上适当调整的。在android1.6开始,就已经支持各种各样的屏幕大小并会自动调整应用的布局以让它们适应每一个屏幕。但是你的应用如果没有顺利的参考上一篇的内容,那么在大屏幕上它可能会偶尔遇到显示问题。为了解决这个问题,屏幕兼容模式会让你的应用能有多一点的机会用在大屏幕上。有两种屏幕兼容模式,它们稍微有些不同:

版本1 (Android 1.6 - 3.1)

系统绘制应用的UI就想在邮票窗口里绘制那样。系统绘制应用的布局会使用黑边填充屏幕剩余的区域。在1.6就引入了屏幕兼容模式这个概念,并且那时候仅为320dp*480dp的原始屏幕而设计(非常关键的一点,你有没有发现很多平板的密度都是mdpi的)。因为有一些老旧的设备执行于android1.5上,并且这个版本可能在将来的不久被废弃掉

版本2 (Android 3.2 或更高)

系统绘制应用的UI会基于默认的尺寸(320dp*480dp)填满屏幕。本质上就像一个"zoom"会放大你的布局,这通常会使你的某些控件模糊。引入版本2的模式是为了在android3.2或者更高的平板上,帮助你的应用即使没有实现上篇讲的内容也能能平板上运行。

大体上,执行于android3.2或更高版本的大屏幕设备允许用户打开屏幕兼容模式,当应用没有在manifest 中明确的声明它支持大屏幕时。在这种情况下,一个图标会出现在系统栏的时钟旁边,用户可以选择屏幕兼容模式开或者关(如图5-3)。如果一个应用明确的声明它不支持大屏幕,那么屏幕兼容模式会一直打开,用户不能关闭它

 

图 5-3. 弹出一个屏幕兼容模式的开关.

作为一个开发者,当应用是否使用屏幕兼容模式时我们有控制权。对于运行在android3.2或以上的大屏幕设备,下面的内容会教我们怎么关闭或者打开屏幕兼容模式,选择权在于你。

5.4.1关闭屏幕兼容模式

如果你的应用的目标主要是低于android3.0的,但为了防止有可能我们的应用会运行到平板上,我们应该关闭它。因为用户打开兼容模式后效果可能不太理想。

默认的, 在android3.2或更高版本上屏幕兼容模式会提供给用户一个选择。只要满足以下的其中一个条件:

1. 你的应用设置android:minSdkVersion 和 android:targetSdkVersion 为"10"或者更小的数字(要参考api level),并且没有明显的声明它支持大屏幕 (<supports-screens> 节点中不要声明它)

2. 你的App设置android:minSdkVersion and android:targetSdkVersion 为"11"或者更高。并且在<supports-screens>节点中声明了它,但值为false(例如android:largeScreens="false")

完全的关闭屏幕兼容模式的用户选项并移除那个图标,我们可以按照下面的方法做:

在manifest 中:

<supports-screens android:xlargeScreens="true"/>

它声明了你的应用支持所有的大屏幕,系统就会一直调整布局来适配屏幕。它忽略<uses-sdk>节点。

在 manifest' <uses-sdk> 节点下, 设置 android:targetSdkVersion 为"11"或更高:

<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="11"/>

就是说你的应用支持android3.0并也可以为大屏幕的设备工作。如果屏幕兼容模式在你改变了上面的设置后还是打开的,那么你就需要检查manifest中的<supports-screens>节点了,确定它没有设置为false。

5.4.2打开屏幕兼容模式 

当我们的应用目标位android 3.2或更高时,我们能使用<supports-screens>节点来设置某些屏幕开打它的兼容模式。

在manifest 中, 添加<supports-screens>节点并指定android:compatibleWidthLimitDp为“320”

<supports-screens android:compatibleWidthLimitDp="320" />

 

这表明,最大的“最小屏幕宽度”为你的应用程序设计320dp。这样一来,只要有一个设备的其中某一个比较小的边只要大于320dp就将提供屏幕兼容模式,并为用户提供可选功能。

注意: 当前屏幕兼容模式只模拟320dp的宽度,如果你的android:compatibleWidthLimitDp大于320,它就不适应其他设备了。

如果你想强制用户使用兼容模式,那么你就可以使用android:largestWidthLimitDp值。

<supports-screensandroid:largestWidthLimitDp="320"/>

看起来好像都是打开兼容模式,但区别在于largestWidthLimitDp是不允许用不关闭的,compatibleWidthLimitDp可以允许用户关闭

5.5 533*320的谎言分辨率

曾经有一段时间,貌似是2010-2011年之间,关于533*320的分辨率是大家讨论的焦点,其实这是一个很简单的问题,只要你了解的每个版本的SDK更新了什么内容。当你发现你的模拟器或手机是800*480,但显示出来的宽高确实533*320时,你需要检测一下你的manifest文件是不是加入了<uses-sdk android:minSdkVersion="3" />。这句话是意思是支持最小SDK版本为1.5,由于1.5和1.6两个版本跨度比较明显,1.6版本后支持自适应。800*480的设备如果你在1.5版本中你用DisplayMetrics获取到的widthPixels和heightPixels是533*320,这并不是BUG或是错误,因为在1.6或以上版本中widthPixels和heightPixels的算法有了变化,它是533*320的基础上在乘以密度的结果。由于800*480的密度为1.5,所以533*320分辨乘以1.5后就是800*480了。为了避免这个问题,你可以使用<uses-sdk android:minSdkVersion="4" />或者大于4。

5.6 创建单面板和多面板布局

用最有效的方法来创建不同的用户体验 为平板和手机是创建具有不同的fragments组合布局,它会给你的用户带来非常棒的用户体验,你能为平板设计多面板布局,为手机设置单面板布局。例如,在平板上一个新的应用需要在左边显示一个文章列表,右边则是文章的内容,并且点击左边的列表,右边的内容会更新。在手机上这2个组件将被分别显示。在fragment中我们有两种技术实践这种设计:

1.多个fragments, 一个activity: 不管设备的大小只使用一个activity,在运行时决定是否结合(多面板)或者分开(单面板)。

2.多个fragments, 多个activity: 在平板上, 一个Activity中放置多个fragments;在手机上, 使用多个区分开来的activities分别控制每一个fragment. 例如, 当平板在的一个Activity中设计2个fragments,  使用同样的activity在手机上的话,效果就会不一样了。手机上执行当你需要切换fragments 时,就会启动另一个Activity来放置第二个fragment。

第一种方法(1个activity; 多个fragments) 你需要在运行时确定屏幕的大小并动态添加每一个fragment ,而非用xml来描述一个布局,因为如果它在XML声明了,你就不能删除那一个fragments了。我们使用方法一的时候,在fragments每一次改变时,可能我们还需要更新action bar。这些因素可能不会影响我们的设计,所以使用方法一效果还是很好的(特别是你有动态添加删除fragments的需求的情况)。动态的东西代码上会复杂一些,你需要权衡一下!!

本节重点介绍了第二个选项,在其中显示在单独的活动时,一个小屏幕的每一个片段。使用这项技术,意味着你可以使用替代的布局文件,为不同的屏幕大小定义不同的fragments组合,

保持fragments代码模块化,简化action bar的管理,让系统在手机上处理所有回栈工作。

下图5-4说明手机和平板下fragments的工作原理:

 

图5-4. 平板和手机使用fragments的布局图

手机上的res/layout/main.xml :

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- "Fragment A" -->
    <fragment class="com.example.android.TitlesFragment"
              android:id="@+id/list_frag"
              android:layout_width="match_parent"
              android:layout_height="match_parent"/>
</FrameLayout>

 

平板上的res/layout-large/main.xml :

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="horizontal"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:id="@+id/frags">
    <!-- "Fragment A" -->
  <fragment class="com.example.android.TitlesFragment"
            android:id="@+id/list_frag"
            android:layout_width="@dimen/titles_size"
            android:layout_height="match_parent"/>
    <!-- "Fragment B" -->
  <fragment class="com.example.android.DetailsFragment"
            android:id="@+id/details_frag"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
</LinearLayout>

 

注意: 大家目前可能看不懂xml文件,因为还没开始写过代码。没关系这里主要是体现平板和手机上布局的不同之处。需要重点说明的是,不要看它在xml设置了布局,其实他还是用代码写的布局,com.example.android.**就是很明显的标志。还有2个xml中是放在不同的文件夹下的, 后者有large的区别哦!!另外为什么平板中的main.xml会多出一个Fragment B而手机中却没有呢?因为平板需要同时在一个activity中显示2个,而手机只需要显示一个A就行了,这依赖于设备,而且在下面的代码中也能用Fragment B是否为空来判定设备是手机还是平板

5.7 使用Action Bar

不管是在平板还是手机上Action Bar是一个重要的UI组件。尽管Action Bar很有用但它并不复杂。下面的内容主要讲的是关于Action Bar和屏幕大小之间的关系和适应情况。下面有一张图, 让我们看看平板和手机中的action bar 是怎样适应屏幕的。如图5-5所示:

 

图5-5 平板与手机中Action Bar布局图

5.8 本章小节

本章简略的说明了android平板与手机支持屏幕的区别,以及兼容模式和谎言分辨率。还以Fragment和ActionBar为例介绍了手机和平板在布局上的不同,我们以后可以根据自己的实际情况加以选择。

本文来自jy02432443,QQ78117253。转载请保留出处,并保留追究法律责任的权利

posted @ 2013-11-18 19:45  jy02432443  阅读(1366)  评论(0编辑  收藏  举报