自定义Toast,支持自定义动画,自定义布局

前言

  • 系统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();
  • 效果
    Toast之自定义动画

自定义布局比较简单,就不去演示。

全部代码

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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自定义 Toast布局,可以按照以下步骤操作: 1. 创建一个 XML 布局文件,用于定义 Toast 的外观。例如,创建一个名为 "custom_toast.xml" 的文件。 2. 在 XML 布局文件中,添加你希望在 Toast 中显示的视图和样式。可以使用任何布局和视图组件,如 TextView、ImageView 等。例如,可以在布局中添加一个 TextView 来显示文本内容。 ```xml <!-- custom_toast.xml --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="16dp" android:background="@drawable/toast_background"> <TextView android:id="@+id/toast_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="14sp" android:text="This is a custom Toast" /> </LinearLayout> ``` 3. 在代码中使用自定义布局来创建 Toast。在你想要显示 Toast 的地方,添加以下代码: ```java // 创建一个 LayoutInflater 对象 LayoutInflater inflater = getLayoutInflater(); // 加载自定义布局文件 View layout = inflater.inflate(R.layout.custom_toast, (ViewGroup) findViewById(R.id.custom_toast_container)); // 创建 Toast 对象 Toast toast = new Toast(getApplicationContext()); toast.setDuration(Toast.LENGTH_SHORT); toast.setView(layout); // 显示 Toast toast.show(); ``` 以上代码会加载自定义布局文件,并将其设置为 Toast 的视图,然后显示 Toast。你可以根据需要修改自定义布局文件和代码中的内容,以适应你的具体需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值