平板与手机支持

还记得上一章的内容吗?分辨率与多屏幕中我们是需用根据不同的屏幕来提供多种让系统可选择的资源,这样你的App就能适用很多设备了。然后有时候你应该想要进一步优化它们。例如平板

提供更多的空间,让你的App能能显示更多的信息,但在手机上时可以会分几个部分显示,不会一次性全部显示出来。大部分情况下平板和手机的体验会有明显的不同。

在android3.0上 ,android 引入了一套新的框架API,它允许我们更有效的设计App,并更好的利用大屏幕。例如3.0新加入的Fragment类,这个类允许你对不同行为的UI组件分成独立的部

分。然后你可以创建多屏设备(例如2屏,3屏手机)的布局啦并使它们结合起来。android3.0还导入了ActionBar这个类,它在屏幕上方提供一个专门的用户界面,来识别APP并提供用户操作

和导航。这种比较先进的技术,大家都很想用吧,不过设备很难搞,我目前还只在国外的视频中看到过3屏的手机,但我们可以在一个屏幕上分几个面板也行的。

本章内容提供指导,在手机和平板上这两种设备上,它帮助你创建一个独特的并优化用户体验的App,并且使用fragments和action bar。

请记住看这一章之前,请看完分辨率那两章,它对你理解本章内容有重要的作用。该文章描述了一个用户界面,它支持不同的屏幕尺寸和密度与灵活的布局和替代位图,并告诉你基本设计原则。

基本设计原则

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

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

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

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

  • 使用ActionBar:它可以根据屏幕上的大小调整 action bar 的布局。

ActionBar是一个UI组件,它可以替代传统的 title bar(是一种目前经常用的通知栏,因为ActionBar是一种比较新的技术,目前国内用的少)。默认的 action bar 在上方的左边显示我们的

App logo,然后是标题。右侧则是可以访问的选择菜单。你可以从选项菜单打开一个items(items可以理解为list或菜单中的一个项目)并直接打开它。你也能添加有导航功能的action bar

作为标签或者下拉列表。直接点击icon还会导航到home页或者相当于一个back键的功能。

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

整布局有很重要的作用。

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

创建单面板和多面板布局


用最有效的方法来创建不同的用户体验 为平板和手机是创建具有不同的fragments组合布局,它会给你的用户带来非常棒的用户体验,你能为平板设计多面板布局,为手机设置单面板布局 。


例如,在平板上一个新的App需要在左边显示一个文章列表,右边则是文章的内容,并且点击左边的列表,右边的内容会更新。在手机上这2个组件将被分别显示。在fragment中我们有两种


技术实践这种设计:


  • 多个fragments, 一个activity: 不管设备的大小只使用一个activity,在运行时决定是否结合(多面板)或者分开(单面板)。
  • 多个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的管理,让系统在手机上处理所有回栈工作。


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

图1. 我们可以吧这种设计看成一种设计模式,左边的是组合关系,它吧所有frag组合到一个act中,右边则是聚合,每一个Act中都有一个frag 他们只有聚合到一起才完成一个完整的功能

就像雁群和大雁(聚合), 大雁和翅膀(组合)。


系统应用于不同的main.xml布局文件取决于屏幕的大小:


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


android 应用手机和平板怎么根据设备显示不同的xml_action



<?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>



android 应用手机和平板怎么根据设备显示不同的xml_action

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


android 应用手机和平板怎么根据设备显示不同的xml_action



<?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>



android 应用手机和平板怎么根据设备显示不同的xml_action

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

用户选择一个item时,Fragment B是怎样被响应的:

  • 如果Fragment B 在Layout里,Activity A会通知iFragment B来更新它自己。
  • 如果Fragment B 不在Layout里, Activity A 会启动 Activity B。

为了实现这个模式,我们需要高度划分好。以下是两条准则:

  • 不要从另一个fragment 直接的操作一个fragment 。
  • 保留所有涉及内容的代码在一个fragment里,而不是放到activity中。

避免直接的从一个fragment 调用另一个fragment,应该在每一个fragment类中定义一个回调接口<在java中接口是深层面向对象必须掌握的知识(个人认为应该是面向抽象编程),不熟的同

学需要补习以下哦>。这里接口的用途是用来传递事件到activity中,当 activity 收到一个由事件引发的回调,那么这个activity 就会响应并适当的处理。

例如Activity A处理item的选择,取决于是否它使用平板或手机布局,代码如下:


android 应用手机和平板怎么根据设备显示不同的xml_action



public class MainActivity extends Activity implements TitlesFragment.OnItemSelectedListener {
    ...

    /** 由于当前MainActivity(Fragment A) 实现了TitlesFragment.OnItemSelectedListener接口
    所以它必须实现onItemSelected(int position)方法,这里是由于选择了Fragment A中的item然后此方法就被执行了
      */
    public void onItemSelected(int position) {
        DisplayFragment displayFrag = (DisplayFragment) getFragmentManager()
                                    .findFragmentById(R.id.display_frag);
        if (displayFrag == null) {
            // 用来显示的Fragment (Fragment B) 
            // 如果displayFrag ==null了就是说明这是在手机上的布局,那么在手机上我们该如果操作呢?
            // 那就是使用intent 传递一个数据并 启动DisplayActivity(Fragment B)
            Intent intent = new Intent(this, DisplayActivity.class);
            intent.putExtra("position", position);
            startActivity(intent);
        } else {
            // 否则就是在平板的上的布局
            // 那么我们直接调用displayFrag.updateContent(position);来更新即可
            displayFrag.updateContent(position);
        }
    }



android 应用手机和平板怎么根据设备显示不同的xml_action


当Activity B(请记住B是用来显示的,A是用来选择item的)启动时候,它会读取数据,这个数据是在Activity A中使用Intent传递过来的。关于这种技术在sdk下的sample下有个例子,

实战篇我们在"实战":)

使用 Action Bar

不管是在平板还是手机上Action Bar是一个重要的UI组件。尽管Action Bar很有用但它并不复杂。反正第二大篇我们会讲的。下面的内容主要讲的是关于Action Bar和屏幕大小之间的关系和适应情况。当我们创建一个Action Bar时,下面这一些最好你们稍微看一下,对你是有帮助的:

  • 当设置一个菜单item作为一个action item时,请避免使用 "always"这个值。在你的菜单资源(属于xml文件)里,如果你想要菜单item出现在action bar下中,请使用android:showAsAction="ifRoom"属性。但是当动作条view没有为菜单提供默认的action时,你还是可能需要“always”的。这种情况还是很少见的。而且如果action item太多,这样会很杂乱,并且会导致标题栏或导航项目重叠。这样根本不好选择!简洁很重要。
  • 当添加一个action item到 action bar时,请使用一个文本标题和一个icon,例如 showAsAction="ifRoom|withText",如果标题太长,那使用一个icon就OK了
  • 在action item中尽量一直提供一个标题,如果你没有打开"withText",就使用toast(android里的一个用来短暂显示内容的控件),这样用户会看到一个短暂的提示,从而进行些什么操作之类的,请千万不要忽视这种细节问题
  • 就算能使用自定义的导航模式,也请避免使用 。最好使用内置嵌入或者下拉模式,这样系统能根据不同的屏幕自动适应。例如当2个标签和其他action item在一起时,如果宽度太窄 ,那么标签就会出现在action bar的下面。如果你非要在 action bar中使用自定义的导航模式或其他自定义的view的话,请在不同的屏幕下彻底的测试它们。

下面有一张图, 让我们看看平板和手机中的action bar 是怎样适应屏幕的。

图2. 你可以看到attach help setting 这三项在平板中是在上面,而在手机中则是出现在下面并且类似于菜单中的一个item了,这就是它们明显的区别。其实看久了你会不会发现平板的大气。在手机上开发的时候,建议界面以简约为主。

使用split action bar

当你的App在android4.0(或更高)运行时,关于action bar有一个额外的模式可用,那就是split action bar。当你打开 split action bar,模式并在竖屏情况下,一个分隔的bar会出现在屏幕的底部用来显示所有的action items。

打开 split action bar, 需要添加 uiOptions="splitActionBarWhenNarrow" 到manifest 中的 <activity> or <application> 节点。让我们来看一下图吧:

图3.

注意: 请记住在android 4.0下才可使用“uiOptions