標籤:
Android可滾動控制項(GridView、ListView、ScrollView等)當使用者滾動到頭的時候會有個邊緣反饋效果,在4.0上預設為Holo藍色效果。 如果您的App自訂了佈景主題色彩,比如Google Play Music的橘黃色。 那麼在滾動內容控制項還是用預設的Holo藍色邊緣效果看起來可能不太協調。這個時候就需要自訂邊緣效果了。
邊緣效果在Android系統中是通過 EdgeEffect 類來實現的,在該類的的建構函式中使用兩個系統圖片來繪製邊緣效果:
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):
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):
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的樣本):
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類, 下載該項目只需要替換兩個圖片即可。
是一個自訂紅色效果的:
Android:自訂滾動邊緣(EdgeEffect)效果