前言
- 系统Toast需要申请通知权限,得不到用户授权,系统Toast将无法展示,部分机型(如小米)还需要打开悬浮窗,才能显示系统Toast。
- 简易的Toast,内容比较简单。
核心思想
-
自定义Toast,核心思想,得到DecorView(即FrameLayout)的子View。
即得到通过setContentView(layoutResID)的布局。再此布局上添加自定义的Toast。
activityWeakReference = new WeakReference<>((Activity) context);
mViewGroup = activityWeakReference.get().getWindow().getDecorView().findViewById(android.R.id.content);
此处用的弱引用,防止Activity出现内存泄漏。
创建Toast对象
public static WbuToast makeToast(Context context, String msg, int duration) {
WbuToast wbuToast = new WbuToast(context);
wbuToast.mShowTime = duration;
wbuToast.msg = msg;
mToastArrayList.add(wbuToast);
return wbuToast;
}
将创建的对象加入对静态LinkedList中。
显示
public void show() {
if (SHOWING || mToastArrayList.isEmpty()) {
return;
}
if (activityWeakReference.get() == null || activityWeakReference.get().isFinishing()) {
mToastArrayList.clear();
return;
}
SHOWING = true;
WbuToast wbuToast = mToastArrayList.getFirst();
wbuToast.initToastViewGroup();
wbuToast.mViewGroup.addView(wbuToast.mToastViewGroup);
wbuToast.mTextView.setText(wbuToast.msg);
wbuToast.playStartAnimation(wbuToast);
}
- 当没有Toast正在显示,从mToastArrayList取出第一个Toast对象进行显示,如果当前Toast所关联的Activity已销毁,则清空缓存链表。
自定义动画
private void playStartAnimation(WbuToast wbuToast) {
ObjectAnimator objectAnimatorOut;
if (wbuToast.mStartObjectAnimators != null && wbuToast.mStartObjectAnimators.length > 0) {
objectAnimatorOut = ObjectAnimator.ofPropertyValuesHolder(wbuToast.mTextView, mStartObjectAnimators);
} else {
//默认动画
objectAnimatorOut = ObjectAnimator.ofFloat(wbuToast.mTextView, "alpha", 0, 1);
}
objectAnimatorOut.setDuration(mStartDuration);
objectAnimatorOut.start();
//开始动画结束后,播放结束动画
wbuToast.playEndAnimation(wbuToast);
}
-
如果没有传入自定义动画,则播放默认的动画。
自定义动画,需要传入PropertyValuesHolder 数组,可以传null。
public void customToastAnimation(PropertyValuesHolder[] startObjectAnimators, PropertyValuesHolder[] endObjectAnimators, int startDuration, int endDuration) {
mStartObjectAnimators = startObjectAnimators;
mEndObjectAnimators = endObjectAnimators;
mStartDuration = startDuration;
mEndDuration = endDuration;
}
自定义布局
public void customToastLayout(int layoutId, int textId) {
mToastLayoutId = layoutId;
mTextViewId = textId;
}
示例用法之自定义动画
WbuToast wbuToast = WbuToast.makeToast(MainActivity.this, "fbgh", WbuToast.LENGTH_LONG);
PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("translationX", 0f, 100f);
PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("translationY", 0f, 100f);
PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("rotation", 0f, 360f);
PropertyValuesHolder holder4 = PropertyValuesHolder.ofFloat("translationX", 100f, 0f);
PropertyValuesHolder holder5 = PropertyValuesHolder.ofFloat("translationY", 100f, 0f);
PropertyValuesHolder holder6 = PropertyValuesHolder.ofFloat("rotation", 360f, 0f);
wbuToast.customToastAnimation(new PropertyValuesHolder[]{holder1, holder2, holder3}, new PropertyValuesHolder[]{holder4, holder5, holder6}, 1000, 1000);
wbuToast.show();
-
效果
自定义布局比较简单,就不去演示。
全部代码
public class WbuToast {
public static int LENGTH_LONG = 3500;
public static int LENGTH_SHORT = 2000;
private static boolean SHOWING = false;
private static final LinkedList<WbuToast> mToastArrayList = new LinkedList<>();
private String msg;
private long mShowTime;
private long mStartDuration;
private long mEndDuration;
private int mToastLayoutId;
private int mTextViewId;
private TextView mTextView;
private ViewGroup mToastViewGroup;
private ViewGroup mViewGroup;
private FrameLayout.LayoutParams mTextLayoutParams;
private WeakReference<Activity> activityWeakReference;
private PropertyValuesHolder[] mStartObjectAnimators;
private PropertyValuesHolder[] mEndObjectAnimators;
private WbuToast(Context context) {
mStartDuration = 300;
mEndDuration = 300;
mToastLayoutId = R.layout.toast;
mTextViewId = R.id.wbu_toast_text_view;
activityWeakReference = new WeakReference<>((Activity) context);
mViewGroup = activityWeakReference.get().getWindow().getDecorView().findViewById(android.R.id.content);
}
private void initToastViewGroup() {
mToastViewGroup = (ViewGroup) LayoutInflater.from(activityWeakReference.get()).inflate(mToastLayoutId, mViewGroup, false);
mTextView = mToastViewGroup.findViewById(mTextViewId);
if (mTextLayoutParams != null) {
mTextView.setLayoutParams(mTextLayoutParams);
}
}
public static WbuToast makeToast(Context context, String msg, int duration) {
WbuToast wbuToast = new WbuToast(context);
wbuToast.mShowTime = duration;
wbuToast.msg = msg;
mToastArrayList.add(wbuToast);
return wbuToast;
}
public void show() {
if (SHOWING || mToastArrayList.isEmpty()) {
return;
}
if (activityWeakReference.get() == null || activityWeakReference.get().isFinishing()) {
mToastArrayList.clear();
return;
}
SHOWING = true;
WbuToast wbuToast = mToastArrayList.getFirst();
wbuToast.initToastViewGroup();
wbuToast.mViewGroup.addView(wbuToast.mToastViewGroup);
wbuToast.mTextView.setText(wbuToast.msg);
wbuToast.playStartAnimation(wbuToast);
}
private void playStartAnimation(WbuToast wbuToast) {
ObjectAnimator objectAnimatorOut;
if (wbuToast.mStartObjectAnimators != null && wbuToast.mStartObjectAnimators.length > 0) {
objectAnimatorOut = ObjectAnimator.ofPropertyValuesHolder(wbuToast.mTextView, mStartObjectAnimators);
} else {
objectAnimatorOut = ObjectAnimator.ofFloat(wbuToast.mTextView, "alpha", 0, 1);
}
objectAnimatorOut.setDuration(mStartDuration);
objectAnimatorOut.start();
wbuToast.playEndAnimation(wbuToast);
}
private void playEndAnimation(WbuToast wbuToast) {
ObjectAnimator objectAnimatorIn;
if (wbuToast.mEndObjectAnimators != null && wbuToast.mEndObjectAnimators.length > 0) {
objectAnimatorIn = ObjectAnimator.ofPropertyValuesHolder(wbuToast.mTextView, mEndObjectAnimators);
} else {
objectAnimatorIn = ObjectAnimator.ofFloat(wbuToast.mTextView, "alpha", 1, 0);
}
objectAnimatorIn.setDuration(mEndDuration);
objectAnimatorIn.setStartDelay(mShowTime);
objectAnimatorIn.start();
objectAnimatorIn.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
if (!mToastArrayList.isEmpty()) {
WbuToast wbuToast = mToastArrayList.getFirst();
wbuToast.mViewGroup.removeView(wbuToast.mToastViewGroup);
mToastArrayList.remove(0);
SHOWING = false;
show();
}
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
public void customToastLayout(int layoutId, int textId) {
mToastLayoutId = layoutId;
mTextViewId = textId;
}
public void customToastPosition(FrameLayout.LayoutParams fl) {
mTextLayoutParams = fl;
}
public void customToastAnimation(PropertyValuesHolder[] startObjectAnimators, PropertyValuesHolder[] endObjectAnimators, int startDuration, int endDuration) {
mStartObjectAnimators = startObjectAnimators;
mEndObjectAnimators = endObjectAnimators;
mStartDuration = startDuration;
mEndDuration = endDuration;
}
}
GitHub地址
(https://github.com/android-greenhand/customToast)
版权声明:本文为weixin_45427063原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。