Android:自定义滚动边缘(EdgeEffect)效果

来源:互联网 发布:台湾网友评论淘宝2016 编辑:程序博客网 时间:2024/06/08 05:50

Android可滚动控件(GridView、ListView、ScrollView等)当用户滚动到头的时候会有个边缘反馈效果,在4.0上默认为Holo蓝色效果。  如果您的App自定义了主题颜色,比如Google Play Music的橘黄色。 那么在滚动内容控件还是用默认的Holo蓝色边缘效果看起来可能不太协调。这个时候就需要自定义边缘效果了。【科学上网软件点击下载(能上youtube、facebook,享受google服务)】

边缘效果在Android系统中是通过EdgeEffect类来实现的,在该类的的构造函数中使用两个系统图片来绘制边缘效果:

帮助
1
2
3
finalResources 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
publicclassResourcesEdgeEffect extendsResources {
    privateintoverscroll_edge = getPlatformDrawableId("overscroll_edge");
    privateintoverscroll_glow = getPlatformDrawableId("overscroll_glow");
 
    publicResourcesEdgeEffect(AssetManager assets, DisplayMetrics metrics, Configuration config) {
        super(assets, metrics, config);
    }
 
    privateintgetPlatformDrawableId(String name) {
        try{
            inti = ((Integer) Class.forName("com.android.internal.R$drawable").getField(name).get(null)).intValue();
            returni;
        }catch(ClassNotFoundException e) {
            Log.e("[ContextWrapperEdgeEffect].getPlatformDrawableId()","Cannot find internal resource class");
            return0;
        }catch(NoSuchFieldException e1) {
            Log.e("[ContextWrapperEdgeEffect].getPlatformDrawableId()","Internal resource id does not exist: " + name);
            return0;
        }catch(IllegalArgumentException e2) {
            Log.e("[ContextWrapperEdgeEffect].getPlatformDrawableId()","Cannot access internal resource id: " + name);
            return0;
        }catch(IllegalAccessException e3) {
            Log.e("[ContextWrapperEdgeEffect].getPlatformDrawableId()","Cannot access internal resource id: " + name);
        }
        return0;
    }
 
    publicDrawable getDrawable(intresId)throwsResources.NotFoundException {
        if(resId == this.overscroll_edge)
            returnContextWrapperEdgeEffect.this.getBaseContext().getResources().getDrawable(R.drawable.overscroll_edge);
        if(resId == this.overscroll_glow)
            returnContextWrapperEdgeEffect.this.getBaseContext().getResources().getDrawable(R.drawable.overscroll_glow);
        returnsuper.getDrawable(resId);
    }
}

然后自定义一个ContextWrapper类(ContextWrapperEdgeEffect.java):

帮助
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
publicclassContextWrapperEdgeEffect extendsContextWrapper {
 
    privatestaticResourcesEdgeEffect RES_EDGE_EFFECT;
 
    publicContextWrapperEdgeEffect(Context context) {
        super(context);
        Resources resources = context.getResources();
        if(RES_EDGE_EFFECT == null)
            RES_EDGE_EFFECT = newResourcesEdgeEffect(resources.getAssets(), resources.getDisplayMetrics(), resources.getConfiguration());
    }
        //返回自定义的Resources
    publicResources getResources() {
        returnRES_EDGE_EFFECT;
    }
}

最后再自定义App中使用到的滚动控件,把Context对象替换为前面自定义的ContextWrapperEdgeEffect类即可(如下是GridView的示例):

帮助
1
2
3
4
5
6
7
8
9
10
11
publicclassGridView extendsandroid.widget.GridView {
 
    publicGridView(Context context, AttributeSet attrs) {
        super(newContextWrapperEdgeEffect(context), attrs);
    }
 
    publicGridView(Context context, AttributeSet attrs, intdefStyle) {
        super(newContextWrapperEdgeEffect(context), attrs, defStyle);
    }
 
}

然后让您的UE同学按照Holo蓝色边缘效果的两张图来提供自定义的两张图即可。

如果您感觉上面这些步骤比较繁琐的话,也可以下载EdgeEffectOverride 这个项目,该项目已经实现了ListView、GridView、ScrollVeiw、ExpandableListView和ViewPager类, 下载该项目只需要替换两个图片即可。

下图是一个自定义红色效果的截图:



Read more: http://blog.chengyunfeng.com/?p=500#ixzz2bH9wX7vf
原创粉丝点击