1. 写在开始
这是学习 Android 的第二个月,前一个月将 Mars 老师的视频看了一边,也将《第一行代码》开了一遍,并将书中的代码都敲了一遍,这个月从网上下载了黑马的 Android 项目教程:智慧北京,用来对 Android 基础知识进行巩固和练习。“智慧北京”算是一个新闻客户端,前前后后我大概写了两遍,第一遍是边看视频边写代码,第二遍没有看视频,是按照自己的回忆和理解来写的,刚开始,感觉很艰辛,视频一关,就忘记怎么写了,不过随着理解的加深、敲代码感觉的提高,后来渐渐的就不再需要忘记,就算忘记,也会根据自己的理解写出,这种感觉棒棒的。
2. 总结
作为一个新闻客户端项目,也是我第一个项目,我从中学到了很多,当然,就算是同一个项目,不同的人会看到、学到不同的东西,对我来说,“智慧北京”这个项目的最大作用,是培养了我的代码感觉,有了充分的练习,能够自己写出代码。这里记录下我学到的知识点:
- 闪屏页和引导页的制作
- ViewPager 和 ListView 的适配器自定义
- Fragment 相关知识的使用
- 开源项目的引用和使用
- UI 架构的策略
2.1 闪屏页和引导页
这个只是针对我这个新手而言是一个知识点,明白了概念以及流程,我觉得闪屏页还有点用处,但是引导页就不明白有什么用了,在用其它 App 的时候我都是快速滑过,然后进入,基本没有看引导页具体有什么内容。
当然,这是我作为一个新手现在的想法,以后可能会有所改变吧。
闪屏的实现方式,我看到的有两种,一种是利用 Handler 发送一个空的延时消息,就可以在闪屏界面停留一定的时间。另一种是利用动画,动画播放的时间就是闪屏停留的时间。
这个知识点我觉得是我学到的最重要的知识点之一了,首先 ViewPager 是第一次用,ListView 之前在看《第一行代码》的时候,继承的是 ArrayAdapter 或者直接使用系统自带的适配器,只是一些基础使用,相对比较简单,这次提高了一点,继承的是 BaseAdapter,与使用 ViewPager 控件时继承的 PagerAdapter 的使用方式很相似,通用性很好;关键是在项目中用了很多次,现在都特别熟悉了,几个方法闭着眼睛都能写,呵呵…
2.3 Fragment 相关知识的使用
之前学习基础的时候也用过,不过那属于练习,用过一次,只是保证以后看到了能够看懂,自己能不能写出来就不一定了。
“智慧北京”这个项目的主界面以及菜单界面都是使用的 Fragment,最开始,FrameLayout、Fragment 类、Fragment 布局文件、FragmentManager 几个概念把我搞蒙了,废了半天劲,才把它们理顺:
- FrameLayout: 是一种布局,非常简单的布局,它只是简单的将自己的 Children 采用叠加方式展现,一般使用 Fragment 的时候都采用这种布局,所以最开始给了我一种错觉:FrameLayout 只能用来添加 Fragment,而 Fragment 只能使用 FrameLayout 布局(没有把你绕晕吧)
- Fragment 类:与 Activity 类似,可以理解为精简版的 Activity,同样需要加载一个布局文件,就是 Fragment 布局文件
- Fragment 布局文件:就是一个普通的布局文件,只是我们将它用作 Fragment 类的布局,所以称为 Fragment 布局文件,但它也可以用作其它布局使用。
- FragmentManager:用来管理 Fragment 类,具体怎么管理,现在可以不用深究,可以简单的理解为它是一个 Fragment 的列表
2.4 开源项目的使用
“智慧北京”项目中用到了三个 GitHub 上的开源项目,分别是:SlidingMenu、xUtils、ViewPagerIndicator。在引用几个开源项目库的时候,也遇到了一些问题(以后会提到),当时废了好大的劲才解决,现在看来,都是小问题啦,哈哈…
SlidingMenu 可以说是现在最流行的菜单样式框架,主要方式是从左边或右边滑出菜单项。简单使用如下(Activity 需要继承 SlidingFragmentActivity),详情参见后期文章。
<code class="language-Java hljs glsl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置菜单页面</span>
setBehindContentView(R.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">layout</span>.left_menu);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//获取菜单对象</span>
SlidingMenu slidingMenu = getSlidingMenu();
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置滑出菜单的方式</span>
slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//滑出菜单后能够看到的主界面的宽度</span>
slidingMenu.setBehindOffset(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">700</span>);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

2.4.2 xUtils
xUtils 翻译过来就是很牛X的工具,的确很牛瓣,“智慧北京”主要使用了其中的 HttpUtils、BitmapUtils 和注解,由于我是练习,就没有用有点偷懒的注解。简单使用如下。
HttpUtils:
<code class="language-Java hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> HttpUtils utils = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> HttpUtils();
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//参数1:请求方式;参数2:请求Url;参数3:回调函数</span>
utils.send(HttpRequest.HttpMethod.GET, GlobalConstants.CATEGORY_URL, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RequestCallBack<String>() {
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onSuccess</span>(ResponseInfo<String> responseInfo) {
String result = responseInfo.result;
processData(result);
}
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onFailure</span>(HttpException e, String s) {
Toast.makeText(mActivity,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"网络访问错误"</span>,Toast.LENGTH_SHORT).show();
}
});</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>
BitmapUtils:
<code class="language-Java hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> BitmapUtils bitmapUtils<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
bitmapUtils = new BitmapUtils(mActivity)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
//设置加载图片时显示的图片
bitmapUtils<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.configDefaultLoadingImage</span>(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.mipmap</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.topnews</span>_item_default)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
//加载图片。参数<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>:显示图片的控件;参数<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>:图片的Url
bitmapUtils<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.display</span>(view,imageUrl)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
基于用户体验考虑,ViewPager 的每次滑动,都有一个指示器来标识 ViewPager 滑动的位置,这个指示器就是 ViewPagerIndicator,具体实现一句两句说不清楚,为了篇幅,这里就不给出代码了,给几张效果图吧。


2.5 UI 架构的策略
这里说的 UI 架构的策略不是想象中的那么高深的东西,而是面临设计好的 UI 图,整理实现方式方法的策略。在实现 UI 时,需要一层一层的去架构,先分析最外围的布局方式,采用什么控件,然后分析下一层的 UI 的布局方式…不一定一次就把所有 UI 都分析出来用什么布局、用什么控件实现,可以分析一层,实现一层,按需实现 UI。