您的位置:首页 > 移动开发 > Android开发

Android自己定义Toast

2017-05-19 19:02 225 查看

一、引言

在开发的过程中你会发现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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: