項目里用到了一個DrawerToast,查了一下是這位兄弟的東西:http://blog.csdn.net/pmavio/article/details/38817885
主要實現了不用等待toast的隊列直接往上疊加、toast的動畫自定義等效果。
根據需求主要要改動的有幾點:
1.toast的位置,要在titlebar正下方。
2.當第二個toast出現的時候,不往上疊加,停止前面toast的動畫、直接在同樣位置顯示第二個toast。
3.每種系統都有個默認的toast動畫效果,這個會跟自定義的動畫疊加,沒辦法達到預計的效果。
因為我很懶··所以直接在源碼上面改動了。
toast的位置
1.DrawerToast的原理思路就是在toast.setView的時候傳入若干布局,最后把需要顯示的view都放到一個LinearLayout里做垂直的線性顯示,看了一下源碼,把initViews里的
mView.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM);改成mView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP);以滿足我要的置頂的功能。
一跑程序發現toast還相對屏幕上方縮進去了一點,檢查代碼發現

LayoutParams params = new LayoutParams(screenWidth, screenHeight); mTopView2.setLayoutParams(params);
這邊在初始化的時候用了屏幕的高度,這個高度還包括了android系統的狀態欄,所以高度是超過應用本身的。然后不知道是由於什么原因導致這個view多出來的部分不是向下面延伸,是縮到屏幕上方去了。所以在初始化的時候,高度扣掉狀態欄高度,再設置titlebar高度的margin,解決第一個問題

//狀態欄高度 public static int getStatusBarHeight(Context context) { Class<?> c = null; Object obj = null; Field field = null; int x = 0, statusBarHeight = 0; try { c = Class.forName("com.android.internal.R$dimen"); obj = c.newInstance(); field = c.getField("status_bar_height"); x = Integer.parseInt(field.get(obj).toString()); statusBarHeight = context.getResources().getDimensionPixelSize(x); } catch (Exception e1) { e1.printStackTrace(); } return statusBarHeight; } int statusBarHeight = getStatusBarHeight(mContext); LayoutParams params = new LayoutParams(screenWidth, screenHeight - statusBarHeight); mTopView2.setLayoutParams(params);
2.第二個問題好辦,只要每次toast要show的時候把之前已經add進去的viewremove掉就可以了。
在show方法里的mView.addView(v, 0);前面加上mView.removeAllViews();
3.這個問題很討厭,本來以為設了動畫本身的默認動畫應該就不見了,查了一下才發現每個系統的默認toast的動畫效果跟后面設的是不沖突的,可以同時存在,所以還必須得去掉系統默認的動畫。
由於DrawerToast本身已經有用反射去獲得mTN下的show和hide方法,所以只要在原先的代碼稍做改動就好了

/** * 通過反射獲得mTN下的show和hide方法 */ private void initTN() { mToast = new Toast(mContext); mToast.setView(mTopView); Class<Toast> clazz = Toast.class; try { mTN = clazz.getDeclaredField("mTN"); mTN.setAccessible(true); mObj = mTN.get(mToast); // 取消掉各個系統的默認toast彈出動畫 modify by yangsq 2014-01-04 Field field = mObj.getClass().getDeclaredField("mParams"); if (field != null) { field.setAccessible(true); Object mParams = field.get(mObj); if (mParams != null && mParams instanceof WindowManager.LayoutParams) { WindowManager.LayoutParams params = (WindowManager.LayoutParams) mParams; params.windowAnimations = -1; } } showMethod = mObj.getClass().getDeclaredMethod("show", null); hideMethod = mObj.getClass().getDeclaredMethod("hide", null); hasReflectException = false; } catch (NoSuchFieldException e) { hasReflectException = true; System.out.println(e.getMessage()); } catch (IllegalAccessException e) { hasReflectException = true; System.out.println(e.getMessage()); } catch (IllegalArgumentException e) { hasReflectException = true; System.out.println(e.getMessage()); } catch (NoSuchMethodException e) { hasReflectException = true; System.out.println(e.getMessage()); } }
最后就是在調用show的時候傳入需要的開始和結束動畫了,這邊根據自己的需求來傳,就不多說了。