首页 > 代码库 > Android自己定义Toast
Android自己定义Toast
一、引言
在开发的过程中你会发现Android自身的Toast提示有很多限制,比方我想自己定义Toast的动画、自己定义一个美观的View显示在Toast中、很多其它的是让Toast显示指定的时长等等。
首先一下效果怎样:
二、原理
自己定义的原理也非常easy,就是给WindowManager加入View和删除View,只是须要设置WindowManager.LayoutParams和View的样式。使其看起来和Android系统的Toast看起来非常相像。
详细代码例如以下:
/** * Custom Toast * * @author Lucky * */ public class ToastHelper { public static final int LENGTH_LONG = 3500; public static final int LENGTH_SHORT = 2000; private WindowManager mWindowManager; private WindowManager.LayoutParams mWindowParams; private View toastView; private Context mContext; private Handler mHandler; private String mToastContent = ""; private int duration = 0; private int animStyleId = android.R.style.Animation_Toast; private final Runnable timerRunnable = new Runnable() { @Override public void run() { removeView(); } }; private ToastHelper(Context context) { // Notice: we should get application context // otherwise we will get error // "Activity has leaked window that was originally added" Context ctx = context.getApplicationContext(); if (ctx == null) { ctx = context; } this.mContext = ctx; mWindowManager = (WindowManager) mContext .getSystemService(Context.WINDOW_SERVICE); init(); } private void init() { mWindowParams = new WindowManager.LayoutParams(); mWindowParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; mWindowParams.alpha = 1.0f; mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT; mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT; mWindowParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; mWindowParams.format = PixelFormat.TRANSLUCENT; mWindowParams.type = WindowManager.LayoutParams.TYPE_TOAST; mWindowParams.setTitle("ToastHelper"); mWindowParams.packageName = mContext.getPackageName(); mWindowParams.windowAnimations = animStyleId;// TODO mWindowParams.y = mContext.getResources().getDisplayMetrics().widthPixels / 5; } @SuppressWarnings("deprecation") @SuppressLint("NewApi") private View getDefaultToastView() { TextView view = new TextView(mContext); view.setText(mToastContent); view.setGravity(Gravity.CENTER_VERTICAL | Gravity.START); view.setFocusable(false); view.setClickable(false); view.setFocusableInTouchMode(false); view.setTextColor(android.graphics.Color.WHITE); Drawable drawable = mContext.getResources().getDrawable( android.R.drawable.toast_frame); if (Build.VERSION.SDK_INT < 16) { view.setBackgroundDrawable(drawable); } else { view.setBackground(drawable); } return view; } public void show() { removeView(); if (toastView == null) { toastView = getDefaultToastView(); } mWindowParams.gravity = android.support.v4.view.GravityCompat .getAbsoluteGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, android.support.v4.view.ViewCompat .getLayoutDirection(toastView)); removeView(); mWindowManager.addView(toastView, mWindowParams); if (mHandler == null) { mHandler = new Handler(); } mHandler.postDelayed(timerRunnable, duration); } public void removeView() { if (toastView != null && toastView.getParent() != null) { mWindowManager.removeView(toastView); mHandler.removeCallbacks(timerRunnable); } } /** * @param context * @param content * @param duration * @return */ public static ToastHelper makeText(Context context, String content, int duration) { ToastHelper helper = new ToastHelper(context); helper.setDuration(duration); helper.setContent(content); return helper; } /** * @param context * @param strId * @param duration * @return */ public static ToastHelper makeText(Context context, int strId, int duration) { ToastHelper helper = new ToastHelper(context); helper.setDuration(duration); helper.setContent(context.getString(strId)); return helper; } public ToastHelper setContent(String content) { this.mToastContent = content; return this; } public ToastHelper setDuration(int duration) { this.duration = duration; return this; } public ToastHelper setAnimation(int animStyleId) { this.animStyleId = animStyleId; mWindowParams.windowAnimations = this.animStyleId; return this; } /** * custom view * * @param view */ public ToastHelper setView(View view) { this.toastView = view; return this; } }
另外分享一个自己定义的Anim:
1.显示Toast的动画:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300" android:fillAfter="true" > <alpha android:fromAlpha="0.0" android:toAlpha="1.0" /> <translate android:fromYDelta="20%" android:toYDelta="0%" /> <scale android:fromXScale="0.5" android:fromYScale="0.5" android:pivotX="50%" android:pivotY="50%" android:toXScale="1.0" android:toYScale="1.0" /> </set>
2.退出Toast的动画:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300" android:fillAfter="true" > <alpha android:fromAlpha="1.0" android:toAlpha="0.0" /> <translate android:fromYDelta="0%" android:toYDelta="20%" /> </set>
给WIndowManager中的View加入动画须要定义一个style,例如以下:
<style name="PopToast"> <item name="@android:windowEnterAnimation">@anim/anim_toast_enter</item> <item name="@android:windowExitAnimation">@anim/anim_toast_exit</item> </style>
最后能够依照例如以下的方式去使用:
ToastHelper .makeText(this, "hello world 你好。哈拉雷速度发说得对", ToastHelper.LENGTH_SHORT) .setAnimation(R.style.PopToast).show();
三、參考资料:
SuperToast: https://github.com/JohnPersano/SuperToasts
Android自己定义Toast