自定義toast的學習(改變toast默認動畫、彈出位置)


項目里用到了一個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);
View Code

這邊在初始化的時候用了屏幕的高度,這個高度還包括了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);
View Code

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());
        }
    }
View Code

最后就是在調用show的時候傳入需要的開始和結束動畫了,這邊根據自己的需求來傳,就不多說了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM