Android可滚动控件(GridView、ListView、ScrollView等)当用户滚动到头的时候会有个边缘反馈效果,在4.0上默认为Holo蓝色效果。 如果您的App自定义了主题颜色,比如Google Play Music的橘黄色。 那么在滚动内容控件还是用默认的Holo蓝色边缘效果看起来可能不太协调。这个时候就需要自定义边缘效果了。【科学上网软件点击下载(能上youtube、facebook,享受google服务)】
边缘效果在Android系统中是通过EdgeEffect类来实现的,在该类的的构造函数中使用两个系统图片来绘制边缘效果:
1
2
3
|
final
Resources res = context.getResources();
mEdge = res.getDrawable(R.drawable.overscroll_edge);
mGlow = res.getDrawable(R.drawable.overscroll_glow);
|
4.0默认的这两个图片如下(点击链接查看图片):
- overscroll_edge:overscroll_edge.png
- overscroll_glow:overscroll_glow.png
所以要实现自定义边缘效果,只需要hack系统在获取这两个图片的时候使用您App提供的图片即可。
Android系统的App是通过ContextWrapper类来获取Resources类,然后通过Resources类来获取各种资源。所以通过自定义这两个类并把自定义的类应用到这些滚动控件中即可。
首先自定义Resources类,在该类中如果判断需要获取上面这两个边缘效果图片,就返回自定义的图片(ResourcesEdgeEffect.java):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
public
class
ResourcesEdgeEffect
extends
Resources {
private
int
overscroll_edge = getPlatformDrawableId(
"overscroll_edge"
);
private
int
overscroll_glow = getPlatformDrawableId(
"overscroll_glow"
);
public
ResourcesEdgeEffect(AssetManager assets, DisplayMetrics metrics, Configuration config) {
super
(assets, metrics, config);
}
private
int
getPlatformDrawableId(String name) {
try
{
int
i = ((Integer) Class.forName(
"com.android.internal.R$drawable"
).getField(name).get(
null
)).intValue();
return
i;
}
catch
(ClassNotFoundException e) {
Log.e(
"[ContextWrapperEdgeEffect].getPlatformDrawableId()"
,
"Cannot find internal resource class"
);
return
0
;
}
catch
(NoSuchFieldException e1) {
Log.e(
"[ContextWrapperEdgeEffect].getPlatformDrawableId()"
,
"Internal resource id does not exist: "
+ name);
return
0
;
}
catch
(IllegalArgumentException e2) {
Log.e(
"[ContextWrapperEdgeEffect].getPlatformDrawableId()"
,
"Cannot access internal resource id: "
+ name);
return
0
;
}
catch
(IllegalAccessException e3) {
Log.e(
"[ContextWrapperEdgeEffect].getPlatformDrawableId()"
,
"Cannot access internal resource id: "
+ name);
}
return
0
;
}
public
Drawable getDrawable(
int
resId)
throws
Resources.NotFoundException {
if
(resId ==
this
.overscroll_edge)
return
ContextWrapperEdgeEffect.
this
.getBaseContext().getResources().getDrawable(R.drawable.overscroll_edge);
if
(resId ==
this
.overscroll_glow)
return
ContextWrapperEdgeEffect.
this
.getBaseContext().getResources().getDrawable(R.drawable.overscroll_glow);
return
super
.getDrawable(resId);
}
}
|
然后自定义一个ContextWrapper类(ContextWrapperEdgeEffect.java):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public
class
ContextWrapperEdgeEffect
extends
ContextWrapper {
private
static
ResourcesEdgeEffect RES_EDGE_EFFECT;
public
ContextWrapperEdgeEffect(Context context) {
super
(context);
Resources resources = context.getResources();
if
(RES_EDGE_EFFECT ==
null
)
RES_EDGE_EFFECT =
new
ResourcesEdgeEffect(resources.getAssets(), resources.getDisplayMetrics(), resources.getConfiguration());
}
//返回自定义的Resources
public
Resources getResources() {
return
RES_EDGE_EFFECT;
}
}
|
最后再自定义App中使用到的滚动控件,把Context对象替换为前面自定义的ContextWrapperEdgeEffect类即可(如下是GridView的示例):
1
2
3
4
5
6
7
8
9
10
11
|
public
class
GridView
extends
android.widget.GridView {
public
GridView(Context context, AttributeSet attrs) {
super
(
new
ContextWrapperEdgeEffect(context), attrs);
}
public
GridView(Context context, AttributeSet attrs,
int
defStyle) {
super
(
new
ContextWrapperEdgeEffect(context), attrs, defStyle);
}
}
|
然后让您的UE同学按照Holo蓝色边缘效果的两张图来提供自定义的两张图即可。
如果您感觉上面这些步骤比较繁琐的话,也可以下载EdgeEffectOverride 这个项目,该项目已经实现了ListView、GridView、ScrollVeiw、ExpandableListView和ViewPager类, 下载该项目只需要替换两个图片即可。
下图是一个自定义红色效果的截图:
Read more: http://blog.chengyunfeng.com/?p=500#ixzz2bH9wX7vf