近来发现一本非常好的Android工具书——《50 Android Hacks》,中文译名叫做 《Android开发必知的50个诀窍》。与其他开发类书籍不同的是,该书并不是系统地讲解每一个知识点,而是以 问题/解决方案 的形式提出开发过程中遇到的问题,并编写Demo程序给出合理的解决方案。本书适用于已经学习过Android开发的程序员,且每个项目对应的源代码都可以在Github 50AH-code 中下载。
对于笔者这种对Android开发有一定了解、希望学习到更好的解决方案的程序员来说,这本书非常受用。书中每一节内容对应一个Demo,简单粗暴地印证了 「Talk is cheap. Show me the code.」 这句名言。在此,我将书中值得注意的地方整理出来,以免遗忘。
Hack1 使用weight属性实现视图的居中显示
问题:无论手机在水平还是竖直情况下,如何固定某View占据父视图的宽度(或高度)百分比?
解决方案:利用ViewGroup的 weightSum 属性和子View的 layout_weight 属性设定View在ViewGroup中的百分比宽度或高度。
Hack2 使用延迟加载以及避免代码重复
问题:构建一些相似的布局布局时,开发者是否可以使用同一套代码?有什么方法可以实现大型组件的“懒加载”?
解决方案:布局中可以直接使用<include/>标签引入其他layout文件,还可以在其中指定属性或修改属性值。加载某些不需要立即呈现或用户可能并不需要的组件时,可以通过ViewStub实现View的延迟加载。ViewStub是一种不可见并且大小为0的视图,可以延迟到运行时填充布局资源。当ViewStub设置被可视或者inflate()方法被调用后,就会填充布局资源。
Hack3 创建定制的ViewGroup
问题:当View大体相同但所处位置按规律排列时,有什么更好构建布局的方式?
解决方案:当View大体相同时,可以使用自定义ViewGroup,更易于项目的维护。修改onMeasure()方法实现ViewGroup对其中View的位置及大小的测量,修改onLayout()方法实现子View的绘制。
Hack4 偏好设置使用技巧
问题:能否使用系统的设置界面主题为应用程序列表美化?
解决方案:利用带有 PreferenceScreen 的XML文件完成布局,代码及Nexus S API 24运行样式如下:
1 |
|
另外,可以实现 OnSharedPreferenceChangeListener 接口来监测EditTextPreference中的文字的变化。
Hack5 使用TextSwitcher和ImageSwitcher实现平滑过渡
问题:如何提升TextView、ImageView等组件切换内容的视觉体验?
解决方案:使用 TextSwitcher 和 ImageSwitcher 添加换入和换出的动画效果,实现平滑过渡。该项目中使用android.R.anim.fade_in和android.R.anim.fade_out添加了淡入淡出效果。
Hack6 为ViewGroup的子视图添加悦目的动画效果
问题:如何提升ListView等组件加载内容的视觉体验?
解决方案:可以使用 ListView.setLayoutAnimation(new LayoutAnimationController(AnimationUtils.loadAnimation(this, R.anim.list_animation), delay)) 方法为ListView的每个条目添加透明度渐变动画和位移动画。值得一提的是,Android坐标系原点在屏幕的左上角,项目中从上而下位移到指定位置的代码如下:
1 |
|
Hack7 在Canvas上显示动画
问题:有没有API可以直接在Android屏幕上绘图?
解决方案:Canvas类封装了所有绘图调用,我们可以 继承View类并重写其onDraw()方法,从而进行图像的绘制以及完成一些动画效果。笔者接下来会结合此项目源码设计并实现一款小游戏。
Hack8 附加Ken Burns特效的幻灯片
问题:如何以幻灯片的形式展示多幅图片?
解决方案:该项目中循环播放图片,并利用 AnimatorSet.playTogether() 方法随机使用一种动画模式。
Hack9 避免在EditText中验证日期
问题:当用户需要在文本框里输入日期信息时,怎样设计才是最好的做法?
解决方案:开发者都知道验证表单里的日期数据是极其令人讨厌的事,因为不同用户输入的方式也大不一样。因此,开发者可以开发一个与EditText相同的Button(使用Button标签下的android:background=”@android:drawable/edit_text”语句),点击该按钮后,一个弹出的DatePickerDialog组件为用户提供日期选择服务。
细心的读者可能会有这样的疑问:为什么不直接为EditText设置一个点击监听器,而非要使用Button呢?答案是:使用Button更安全,因为用户无法修改Button的文本内容。如果使用EditText,并且只设置了点击监听器,用户可以通过光标获取该控件的焦点,这样便可以绕过DatePicker控件直接修改EditText的文本内容。
Hack10 格式化TextView的文本
问题:如何在TextView中添加不同样式的文本和链接?
解决方案:开发者可以使用 Html.fromHtml(String) 方法在TextView的文本内容中嵌入HTML代码,要注意的是嵌入HTML代码之后调用 TextView.setMovementMethod(LinkMovementMethod.getInstance()) 将TextView设置为可点击状态。开发者还可以使用SpannableString类为字符串中的指定字符设置前景色与背景色。
请注意:在XML文本中,像“<”和“&”字符都是非法的。因此,为了在XML中插入非法字符,开发者可以使用<![CDATA[……]]>语句,省略号处的语句允许使用“<”和“&”等字符。