Android开发笔记(八十二)SDK版本兼容

来源:互联网 发布:数据归一化公式 编辑:程序博客网 时间:2024/05/23 00:06

统一主题与风格

Android控件很多属性都有默认值,比如文字默认黑色、编辑框默认透明背景等等,但因为android是开源的,各厂商都会自行修修补补,所以很多时候默认值并不靠谱。举例如下:
1、在某些低版本的Android上,如不指定文字颜色textColor,则默认的文字颜色是白色;
2、编辑框有的默认透明背景加一根底线,有的默认白色圆角背景;
3、主题Theme.Holo默认是浅灰背景,但有的品牌手机上改成了深灰背景;
4、调用View的getDrawingCache方法对指定控件截图,默认背景是黑色,而不是我们在UI上看到的透明背景,是不是很惊讶?所以截图前要先设置好背景色。


所以,为了让app在不同设备上都是一样的显示风格,就得自己设置期望的各种属性值,另外也尽量不用系统自带的主题,如有可能自定义主题风格,这样即使设备厂商修改了默认属性值,app也仍然保持统一的风格。


兼容SDK各版本

Android每隔一段时间就会推出新版本与新的SDK,手机上的Android版本也是各不相同,从最早的2.2到4.0到5.0再到6.0,SDK里的API更新很频繁,有时候app用到高版本的api,同时又想兼容低版本的手机,可在工程中作如下处理:
1、AndroidManifest.xml里的uses-sdk标签,指定兼容的sdk最低版本号minSdkVersion,同时指定编译用的sdk目标版本号targetSdkVersion;
2、代码中判断当前设备的sdk版本号,即获取Build.VERSION.SDK_INT的值,判断当前版本号如果小于指定版本,则采取低版本的处理逻辑;如果当前版本号大于指定版本,则采取高版本的处理逻辑。
3、代码中有调用高版本api的地方,要在对应方法前加上“@TargetApi()”标签或者“@SuppressLint("NewApi")”标签,这两个标签的区别是:
@TargetApi() 只屏蔽某一新api开始才能使用的方法报的android lint错误;
@SuppressLint("NewApi") 屏蔽一切新api中才能使用的方法报的android lint错误;
注意,不管是TargetApi方式还是NewApi方式,都只能消除ADT的编译错误,app内部处理时,还是得依据Build.VERSION.SDK_INT做分支判断。


support包的兼容

Android的sdk还额外提供了几个支持包,包括android-support-v4.jar、android-support-v7-***.jar、android-support-v13.jar等等,推出支持包的目的是让低版本的Android也能使用高版本新增的控件。下面是支持包中常用的几个控件:
android.support.v4.view.ViewPager、android.support.v4.app.Fragment
android.support.v7.app.ActionBar、android.support.v7.app.ActionBarActivity
android.support.v13.app.FragmentTabHost


对于v4的控件,我们在代码中import相关类就好了,但是对于v7的控件,光光import是不够的。只是import支持包v7的控件类,虽然编译时没有问题,但运行时就会报错“java.lang.NoClassDefFoundError: android.support.v7.appcompat.R$styleable”。这是因为v7的完整包除了jar文件,还有资源文件,所以得把v7包作为一个库工程引用进来。

以android-support-v7-appcompat.jar为例,在ADT上依次选择菜单“File”——“Import”——“Existing Android Code Into Workspace”——“Next”,然后选择sdk安装目录下的appcompat路径,如“sdk\extras\android\support\v7\appcompat”。可是导入之后,编译又报错:“android:Widget.Material.ActionButton”找不到,解决办法是把project.properties中的“target=android-19”改为“target=android-23”,注意库工程和自己的工程都要改。

这下编译总算没问题了,博主兴冲冲启动app,没想到进入页面依然异常退出,日志报错“Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.”真是一波三折呀,出现该错误的缘由,是ActionBarActivity的派生类必须使用v7的appcompat主题,具体的解决办法要修改AndroidManifest.xml,找到指定类的标签,加上这么一个属性:“android:theme="@style/Theme.AppCompat.Light"”,重新编译运行,app就能正常使用了。


兼容5.0的水波动画

Android5.0之后新加了水波动画RippleDrawable,现在想在4.X系列的手机上使用水波效果,就要自定义水波控件了。其中经过博主验证,下面三个水波控件是可用的,其效果各有千秋,具体介绍如下:

1、RevealLayout
RevealLayout继承自LinearLayout,可用作视图背景水波,也可用作单个控件的水波。
RevealLayout标签可在布局文件中直接使用。
下载RevealLayout的代码可到 https://github.com/kyze8439690/RevealLayout

2、RippleView
RippleView继承自RelativeLayout,只可用做视图背景水波,也可用作单个控件的水波。
RippleView标签可在布局文件中直接使用。
下载RippleView的代码可到 https://github.com/traex/RippleEffect

3、MaterialRippleLayout
MaterialRippleLayout继承自FrameLayout,只可用做视图背景水波,但视图上如果有其它控件如按钮,则水波会被按钮遮挡住。
MaterialRippleLayout不可在布局文件中直接使用。要在代码中以如下方式调用:
    MaterialRippleLayout.on(layout1)        .rippleColor(Color.BLACK)        .rippleAlpha(0.2f)        .rippleHover(true)        .create();
下载MaterialRippleLayout的代码可到 https://github.com/balysv/material-ripple



点击下载本文用到的兼容水波动画的工程代码



点此查看Android开发笔记的完整目录
0 0