当前位置: 代码迷 >> Android >> 某预下市Android阅读产品界面开发揭秘
  详细解决方案

某预下市Android阅读产品界面开发揭秘

热度:100   发布时间:2016-05-01 14:10:20.0
某预上市Android阅读产品界面开发揭秘

刚接触android平台时,个人觉得界面布局最难。本人试图就自己最近做过的一个产品(请耐心等待,大概本年度中与大家相见),讲解其界面的制作过程,希望可以给为UI布局感到困惑的人点灵感。贴张图先:请参见附件图1(哎,抱怨一句,图有点大,Javaeye容量有限,不能直接上图)

该图的上下文是:它是一个阅读产品的截图,底部有6个操作按钮,用来切换主窗体界面,当前所在的主窗体为“我的书架”。底部6个操作按钮之上的是“我的书架”中存放的各种书籍的分类,包括“最近”、书籍、原创等分类。用户想要阅读具体某本书时,只要点击该书的封面图片,如图所示,会出现一个封面背景框,然后进入阅读界面享受阅读。业务情况大致是如此。

读者可以在往下看之前,先对这个图进行一些揣摩,如果是你自己来做这个界面布局,你将怎么实现?也许比我的做法更好J,多多交流啊。二话不说,我开始介绍我的做法:

首先,我将界面分成三大部分:头部head_bar(具体包括logo、时间、关闭按钮、“我的书架”文本等元素)、中间体部layout_body_root(具体包括书籍组件、书籍分类元素)、底部foot_bar(具体包括各种切换主窗体的操作按钮)。这3者是呈上中下的自然顺序而堆砌,故而我采用Android里最为常用的LinearLayout作为他们的布局容器,一般情况下,它支持的顺序便是线性的从左到右、由上到下的自然顺序。

接着,我们首先介绍头部head_bar的具体布局,它主要包含logo(ImageView)、时间(TextView)、关闭按钮(ImageButton)、“我的书架”文本(TextView)等元素,这时候我们应该采用什么布局容器来包容他们呢?仔细观察,他们具有如下特点:logo元素居容器左侧,时间元素居容器中部,关闭按钮居容器右侧,“我的书架”文本居时间元素的正下方。那么这样一来,我们很容易根据这个布局特点来遐想一些android里面的布局形如“android:layout_xxx”属性(也许这个很容易来自于你必须对android的布局有一些基础性的了解,所以在阅读这篇文章之前,建议你对android的布局要有个系统性的理解吧J),如此一来,根据我们之前对他们的布局描述是,比如“logo元素居容器左侧”,那么我们可以将其翻译成android:layout_alignParentLeft="true",“时间元素居容器中部”翻译成android:layout_centerHorizontal="true",“关闭按钮居容器右侧”翻译成android:layout_alignParentRight="true",“‘我的书架’文本居时间元素的正下方”翻译成android:layout_below="@+id/time"(其中@+id/time表示时间元素的id)和android:layout_centerHorizontal="true"。有了这些“android:layout_xxx”字样,自然而然其父容器当然就是RelativeLayout,因为只有RelativeLayout才真正支持这些属性。以下将具体代码贴出:

<RelativeLayout

?????????????????? android:id="@+id/head_bar"

?????????????????? android:background="@drawable/head_bar_bg"

?????????????????? android:layout_width="wrap_content"

?????????????????? android:layout_height="wrap_content">??????

?????????????????? <ImageView

??????????????????????????? android:id="@+id/logo"

??????????????????????????? android:src="@drawable/logo"

??????????????????????????? android:layout_width="wrap_content"

??????????????????????????? android:layout_height="wrap_content"

??????????????????????????? android:layout_marginTop="2px"

??????????????????????????? android:layout_marginLeft="5px"

??????????????????????????? android:layout_alignParentLeft="true">

?????????????????? </ImageView>

?????????????????? <TextView

??????????????????????????? android:id="@+id/time"

??????????????????????????? android:layout_width="wrap_content"

??????????????????????????? android:layout_height="wrap_content"

??????????????????????????? android:layout_marginTop="4px"

??????????????????????????? android:layout_centerHorizontal="true">

?????????????????? </TextView>

?????????????????? <ImageButton

??????????????????????????? android:id="@+id/btn_close"

??????????????????????????? android:src="@drawable/close_btn"

??????????????????????????? android:layout_width="wrap_content"

??????????????????????????? android:layout_height="wrap_content"

??????????????????????????? android:layout_marginTop="3px"

??????????????????????????? android:layout_marginRight="2px"

??????????????????????????? android:layout_alignParentRight="true"

??????????????????????????? android:background="@null">

?????????????????? </ImageButton>

?????????????????? <TextView

??????????????????????????? android:id="@+id/body_title"

??????????????????????????? android:layout_width="wrap_content"

??????????????????????????? android:layout_height="wrap_content"

??????????????????????????? android:layout_below="@+id/time"

??????????????????????????? android:layout_marginTop="3px"

??????????????????????????? android:layout_centerHorizontal="true"

??????????????????????????? style="@style/bodyTitleText">

?????????????????? </TextView>

???????? </RelativeLayout>

其中,android:layout_marginTop等属性属于位置的微调部分。这样一来,关于头部的布局便实现了。

???????? 接下来继续介绍中间体部的布局。注意我之前对该主窗体的描述——切换,也就是说主窗体是由多个窗体共同享受的,用户通过点击底部按钮对其进行切换。那要怎么实现切换效果,聪明的你肯定知道,比如现在要从窗体A切换到窗体B,就是通过设置A窗体为不可见,而将窗体B设置为可见,即可实现他们之间的切换。换句话说,实际上主窗体是有6个窗体(为什么是6个?因为底部按钮有6)共用使用,你可以这样假想,现在的主窗体是由窗体A放置最前面,其他窗体BCDEF都是放置在窗体A底下,被遮盖住而已。那么,我们自然而然想到android里实现遮盖布局的容器FrameLayout。以下贴出代码,其中android:layout_weight="1"很有用,它将接受底部的存在,为底部腾出一定的空间来。

??? <FrameLayout

?????????????????? android:id="@+id/layout_body_root"

?????????????????? android:layout_width="fill_parent"

?????????????????? android:layout_height="fill_parent"

?????????????????? android:background="@drawable/body_bg"

?????????????????? android:layout_weight="1">

???????? </FrameLayout>

最后我们来讲讲底部布局实现。底部的6个按钮从左到右排列,彼此紧挨,这便是线性布局的特征。值得一提的是,底部按钮被选中时,有透明效果,其实这是将另外一张图片放置于按钮图片之上,并且设置该图片的属性:android:background="@null",也即设置上层的图片属性android:background="@null",如此一来,便可实现透明。

以下贴出代码:

??? <RelativeLayout

?????????????????? android:id="@+id/foot_bar"

?????????????????? android:background="@drawable/foot_bar_bg"

?????????????????? android:layout_width="wrap_content"

?????????????????? android:layout_height="wrap_content">

?????????????????? <ImageView

??????????????????????????? android:id="@+id/imageView_btn_bar"

??????????????????????????? android:src="@drawable/nav_btn_bar"

??????????????????????????? android:layout_width="fill_parent"

??????????????????????????? android:layout_height="wrap_content">

?????????????????? </ImageView>

?????????????????? <LinearLayout

??????????????????????????? android:id="@+id/btn_bar"

??????????????????????????? android:layout_height="wrap_content"

??????????????????????????? android:layout_width="fill_parent">

??????????????????????????? <ImageButton

???????????????????????????????????? android:id="@+id/btn_book_shelf"

???????????????????????????????????? android:src="@drawable/nothing"

???????????????????????????????????? android:layout_width="51px"

???????????????????????????????????? android:layout_height="56px"

???????????????????????????????????? android:layout_marginLeft="5px"

???????????????????????????????????? android:background="@null"

???????????????????????????????????? android:layout_gravity="bottom">

??????????????????????????? </ImageButton>

??????????????????????????? <ImageButton

???????????????????????????????????? android:id="@+id/btn_book_library"

???????????????????????????????????? android:src="@drawable/nothing"

???????????????????????????????????? android:layout_width="51px"

???????????????????????????????????? android:layout_height="56px"

???????????????????????????????????? android:background="@null">

??????????????????????????? </ImageButton>

??????????????????????????? <ImageButton

???????????????????????????????????? android:id="@+id/btn_book_collection"

???????????????????????????????????? android:src="@drawable/nothing"

???????????????????????????????????? android:layout_width="51px"

???????????????????????????????????? android:layout_height="56px"

???????????????????????????????????? android:background="@null">

??????????????????????????? </ImageButton>

??????????????????????????? <ImageButton

???????????????????????????????????? android:id="@+id/btn_private_info"

???????????????????????????????????? android:src="@drawable/nothing"

???????????????????????????????????? android:layout_width="51px"

???????????????????????????????????? android:layout_height="56px"

???????????????????????????????????? android:background="@null">

??????????????????????????? </ImageButton>

??????????????????????????? <ImageButton

???????????????????????????????????? android:id="@+id/btn_book_query"

???????????????????????????????????? android:src="@drawable/nothing"

???????????????????????????????????? android:layout_width="51px"

???????????????????????????????????? android:layout_height="56px"

???????????????????????????????????? android:background="@null">

??????????????????????????? </ImageButton>

??????????????????????????? <ImageButton

???????????????????????????????????? android:id="@+id/btn_system_config"

???????????????????????????????????? android:src="@drawable/nothing"

???????????????????????????????????? android:layout_width="51px"

???????????????????????????????????? android:layout_height="56px"

???????????????????????????????????? android:background="@null">

??????????????????????????? </ImageButton>

?????????????????? </LinearLayout>

???????? </RelativeLayout>

以上,便是整体布局的总体介绍。以下再贴张eclipse的图,其中注意右侧head_bar选中的情况,head_bar对应于左侧被选中的红色框。请参见附件图2

接着,我们再来介绍书籍元素的实现,这里面还是相当有含量的。首先,我们可以看到主窗体有多个这样的书籍元素,所以我们要用组件的眼光来看待它,也就是说,把它设计成一个组件,与android平台提供的View一样的组件。这个组件主要包括元素:书名(还有,书名过长时,用省略号替代)、出版日期、书籍封面(还有,书籍封面按下的背景框)、星级评定等界面元素。这些界面元素从上至下排列,显然是线性布局LinearLayout。所以,我们初步的思想是创建一个BookInfoLayout对象,继承于LinearLayout(考虑到书籍组件中的数据是可变的,所以我们决定不再使用xml来布局,而使用Java代码来创建布局)。然后,只要顺序地创建并将各个组件添加到LinearLayout中即可。值得一提的是书籍封面按下背景框的与星级评定的实现。我们首先来看书籍封面按下背景框的实现。一般替换系统默认的背景图有2种做法,一种是代码实现法,即在实现代码中捕捉鼠标按下和松开事件,替换相应图片。基于不侵入代码想法,我决定采用xml做法,即替换被按下时,系统默认采用的图片。具体做法是在drawable文件夹下创建book_button.xml文件,具体内容如下:

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

??? <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/book_default" />

??? <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/book_default" />

??? <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/book_focus" />

??? <item android:drawable="@drawable/book_default" />

</selector>

由上代码可见,我们替换了系统默认的图片,它们分别是按钮会有的四种情况,聚焦而不被按下、聚焦并且被按下、失焦而被按下、失焦并且不被按下(即普通静态情况)。再来是星际评定的情况,默认情况下无参创建的RatingBar会是大图标的,所以小图片的星星需要特别指定,具体代码如下:

RatingBar ratingBar = new RatingBar(context,null,android.R.attr.ratingBarStyleSmall);

这样一来,我们的书籍组件便创建成功了,你就可以把它当做像View一样的组件来使用了。比如你可以把它们放入GridView当中,如此一来,当读者使用横屏来看书的时候,便可以自动适应,而不需要我们再手动编程去计算横宽屏的大小来调整组件放置个数了,另外android平台还可以为GridView增加一些额外的特效,例如当打开“我的书架”窗体时,让书籍组件一个一个冒出来的效果,有时候也可以让用户眼睛为之一亮,贴张横屏的图先:请参见附件图3

  相关解决方案