Roman Guy的Android Trick系列文章笔记(三)
以下所涉及的所有文章都被墙了。。
Android2.2以后的SDK自带的工具HierachyViewer提供了一个新的功能:Capture PSD。也就是说,它可以把设备当前的ui生成成一个photoshop文件。这个功能非常有用,它可以帮助你debug ui。。
需要注意的是,当你的手机烧制的是USER版本时,HierachyViewer不能工作,这是出于安全的原因。不过它可以在模拟器工作。
ScrollView是Android中最常用的widget之一,并且同时也是非常简单易用的wdiget之一。当要在屏幕上显示很多内容时,把它们全部丢进一个ScrollView就搞定了。甚至,ScrollView只能接收一个子节点,如果添加多个就会出错。由于它很简单,所以在使用的时候就需要一点小技巧。
有的时候需要实现一个类似版权信息的页面,只有用户滚动到最底部,才能看到确定和取消按钮。假如,版权信息用一个TextView来展现,而这个TextView时长时短。这时可以如下实现:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/scroller" android:layout_width="fill_parent" android:layout_height="fill_parent" android:fillViewport="true" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="6dip" android:paddingRight="6dip" android:paddingTop="6dip" android:textAppearance="?android:attr/textAppearanceMedium" android:text="Welcome to My Application" /> <View android:layout_width="fill_parent" android:layout_height="1dip" android:background="#ff106510" android:layout_marginLeft="6dip" android:layout_marginRight="6dip" android:layout_marginTop="6dip" android:layout_marginBottom="12dip" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1.0" android:paddingLeft="6dip" android:paddingRight="6dip" android:paddingBottom="6dip" android:text="@string/hello" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@android:drawable/bottom_bar" android:gravity="center_vertical"> <Button android:layout_width="0dip" android:layout_weight="1.0" android:layout_height="wrap_content" android:text="Accept" /> <Button android:layout_width="0dip" android:layout_weight="1.0" android:layout_height="wrap_content" android:text="Refuse" /> </LinearLayout> </LinearLayout> </ScrollView>
需要注意的两点是:1.TextView的android:layout_weight设置未1.0,这样做会使它比ScrollView短时使用可用的空白区域。并且这个只有android:fillViewport="true"时才生效。
3.Gingerbread and 32 bits windows
Roman Guy和Chet Haase在Devoxx做了一次演讲,他们的ppt其中的一页,在很多Android开发网站上引起广泛兴趣:
因此他需要说点什么:
* 现在(指在Gingerbread中,下同)应用程序可以使用32bit的window(即便是透明window,那也是32bit的)
* 现在应用程序可以强制bitmap以32bit加载
* 现在应用程序阻止banding(他的下一篇文章会介绍)
* OpenGL的window依然保持了16bit,因为兼容性问题。一些游戏应当不需要假定这个格式在GB中不存在。我们不希望破坏应用程序。(原文:OpenGL windows remain 16 bits in Gingerbread for compatibility reasons. Some games assume this format and should not. But they do, and we don’t like breaking applications.)
* 现在OpenGL应用程序也可以使用32bit window了。
总结起来,Gingerbread的升级并没有特意为系统添加32bit图形的支持,系统本来就一直支持。Gingerbread只是简单地在更多的情况中把32bit作为默认方式。
文后有一些讨论:
A:UI这样改变了之后,系统在绘制图形时是不是更快了呢,或者还是如果不使用32bit图形,设备性能就会降一截呢?
答:透明的bitmap以前已经是32bit的了,并且在作blend(图片的一种处理方式)操作是要转换成16bit的,所以在这种情形下16bit的会快一点。32bit不透明bitmap会比16bit的绘制更快,因为内存拷贝时更方便。如果你的应用因为内存原因而对不透明图片使用16bit,我也觉得这不会是问题。当然了,如果你强制你的bitmap以16bit加载,那么现在会有一个自动的16bit转32bit的过程。总地来说这和之前没有太大不同,只是app会消耗更多内存。
B:那这不是说Gb只能运行在高端机器上吗?
答:这不意味Gb只能在高端机上运行。因为这一点也没有改变硬件需求。再者,那些在API Level 8上或者更早的版本开发的app,它们在Gb上运行同样会以32bit加载bitmap,而不是16bit,除非你需要这么做。
4. Bitmap quality, banding and dithering
这篇文章主要介绍了,选用哪种像素规格的bitmap会有更好的显示效果。全文从头至尾挨个论证了几种解决图片显示效果的方案,过程我不详述了,因为图像处理着一块我不熟悉。
但是下面两张图可以大致了解本文的意思:
1.
我们可以很明显的看到,在32bit和16bit的window中显示同一种像素规格(ARGB_8888)的bitmap时不同效果。前者效果更好。
2.
这张图展示的是多种像素规格bitmap在不同bit的window中显示的效率.
结论:这个简单的性能测试非常清晰的展示了使用兼容的格式是绘制bitmap最有效率的途径,例如,32bit bitmap在32 bit window上绘制或者16bit或565格式的bitmap在16bit window上绘制 效果都会很好。因为这个原因,你应该一直检查你的bitmap和window的格式,并且保证他们相互兼容。你可以在creating an empty bitmap或者decoding a resource or stream的时候选择bitmap的格式。你可以通过调用Bitmap.getConfig()来查看当前存在的bitmap的格式。你可以在onCreate()方法中通过getWindow().getAttributes().format来查询当前window的格式。你同样可以参考本篇文章的源代码来查看如何选择一个特定格式。
btw:在下一篇文章中我会介绍一下dither和banding这两个概念。