Android自己定义Toast

相逢意气为君饮,系马高楼垂柳边。这篇文章主要讲述Android自己定义Toast相关的知识,希望能为你提供帮助。
一、引言在开发的过程中你会发现android自身的Toast提示有很多限制,比方我想自己定义Toast的动画、自己定义一个美观的View显示在Toast中、很多其它的是让Toast显示指定的时长等等。

首先一下效果怎样:

Android自己定义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的动画:【Android自己定义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










    推荐阅读