在開發Android應用時,一般我們都會用toast來彈出提示消息,簡單高效。但是在不同的手機下toast顯示的位置和樣式可能會不同,而且系統自帶的toast樣式奇丑(個人覺得...),那么怎樣定制一個個性的toast提示框呢。。。 今天我就分享一下自己寫的自定義toast,不足之處還請大家多多指點。(后邊有效果圖)
1、因為toast的特性,所以我們定義toast為單例模式。
private static ZToast instance; //單例的 private View mToastView;//自定義toast view private TextView mTextView; private Boolean mIsShow;//記錄狀態 是否在顯示 private Timer mTimer;//定時器 public synchronized static ZToast getInstance(Context context) { if (instance == null) instance = new ZToast(context); return instance; } private ZToast(Context context) { mIsShow = false;// 記錄當前Toast的內容是否已經在顯示 //這里初始化toast view mToastView = LayoutInflater.from(context).inflate(R.layout.common_toast, null); //用來提示的文字 mTextView = ((TextView) mToastView.findViewById(R.id.toast_text)); //初始化計數器 mTimer = new Timer(); // 設置布局參數 setParams(); }
2、接着設置布局樣式:
private LayoutParams mParams; private void setParams() { mParams = new WindowManager.LayoutParams();//初始化 mParams.height = WindowManager.LayoutParams.WRAP_CONTENT; //高 mParams.width = WindowManager.LayoutParams.WRAP_CONTENT; //寬 mParams.format = PixelFormat.TRANSLUCENT; mParams.windowAnimations = R.style.custom_animation_toast;// 設置進入退出動畫效果 mParams.type = WindowManager.LayoutParams.TYPE_TOAST; mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; mParams.gravity = Gravity.BOTTOM; //對其方式 mParams.y = 45; //下間距 }
3、自定義toast彈出風格 動畫的效果 。 toast_styles.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="custom.animation.toast" parent="@android:style/Animation.Toast"> <item name="android:windowEnterAnimation">@anim/toast_enter</item> <item name="android:windowExitAnimation">@anim/toast_exit</item> </style> </resources>
toast_enter.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:duration="1" android:fromXDelta="0" android:fromYDelta="0" android:toXDelta="0" android:toYDelta="85" /> <translate android:duration="350" android:fillAfter="true" android:fromXDelta="0" android:fromYDelta="0" android:interpolator="@interpolator/accelerate_quad" android:toXDelta="0" android:toYDelta="-105" /> <alpha android:duration="100" android:fromAlpha="0" android:toAlpha="1" /> <translate android:duration="80" android:fillAfter="true" android:fromXDelta="0" android:fromYDelta="0" android:startOffset="350" android:toXDelta="0" android:toYDelta="20" /> </set>
toast_exit.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:duration="500" android:fromYDelta="0" android:interpolator="@interpolator/accelerate_quad" android:toYDelta="50%p" /> <alpha android:duration="500" android:fromAlpha="1.0" android:toAlpha="0.0" /> </set>
4、common_toast.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/bg_common_toast" android:orientation="horizontal" > <TextView android:id="@+id/toast_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:gravity="left|center" android:textColor="@android:color/black" android:textSize="@dimen/toast_font_size" /> </LinearLayout>
以上,這樣就得到了一個自定義的帶動畫效果的view容器了。然后,怎么調用呢? 別急,我們需要再寫個方法。。
public void show(String text, int mShowTime) { if (mIsShow) {// 如果Toast已經在顯示 就先給隱藏了 if (ManageApp.mWdm != null && mToastView != null) ManageApp.mWdm.removeView(mToastView); // 取消計時器 if (mTimer != null) { mTimer.cancel(); mTimer = new Timer(); } } //設置顯示內容 mTextView.setText(text); //設置顯示狀態 mIsShow = true; // 將其加載到windowManager上 ManageApp.mWdm.addView(mToastView, mParams); //設置計時器 mTimer.schedule(new TimerTask() { @Override public void run() { ManageApp.mWdm.removeView(mToastView); mIsShow = false; } }, (long) (mShowTime == Toast.LENGTH_LONG ? 2200 : 1200)); }
大家會問mWdm是個神馬? 其實它就是WindowManager(public static WindowManager mWdm;),最終還是需要使用它來吧view顯示在屏幕上的。我們把它定義在程序的Application類中,並在oncreate()里初始化mWdm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); 這樣就能保證他的生命周期會比我們的activity長,從而在執行計時器的時候不會報各種各樣的異常。(如果有其他更好的辦法,望告知。)
然后,在其他類中,使用
ZToast.getInstance(mContext).show("我是自定義的toast",Toast.LENGTH_LONG );
效果如下: