android 自定义Toast增加点击事件、Toast弹出隐藏动画、Toast宽度为match_parent

在自定义Toast的时候,可能会用到点击事件,但是android系统本身Toast只是用于提示,并不支持点击事件,即使自定义Toast也不支持点击事件,查看Toast源码可以发现,其内部的TN.class(该为私有类,外部调用不了)里面的WindowManager.LayoutParams 的flags属性有WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,如图:

这里写图片描述

所以,要想Toast开启点击事件,需要通过反射的方法来改变其内部的WindowManager.LayoutParams的flags,去掉WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE这个属性,

实现如下:

public class ClickToast{

    private static Toast mToast;
    private static Button btn;

    public static void showToast (final Context context, int duration){

        if(mToast == null){
            LayoutInflater inflater = (LayoutInflater)context.getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            //自定义布局
            View view = inflater.inflate(R.layout.toast_mytoast, null);
            btn= view.findViewById(R.id.btn);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //这里可以做点击操作
                }
            });
            mToast = Toast.makeText(context.getApplicationContext(), "", duration);
            //这里可以指定显示位置
    //            mToast.setGravity(Gravity.BOTTOM, 0, 0);

            mToast.setView(view);
        }

        try {
            Object mTN ;
            mTN = getField(mToast, "mTN");
            if (mTN != null) {
                Object mParams = getField(mTN, "mParams");
                if (mParams != null
                        && mParams instanceof WindowManager.LayoutParams) {
                    WindowManager.LayoutParams params = (WindowManager.LayoutParams) mParams;
                    //显示与隐藏动画
                    params.windowAnimations = R.style.ClickToast;
                    //Toast可点击
                    params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                            | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

                    //设置viewgroup宽高
                    params.width = WindowManager.LayoutParams.MATCH_PARENT; //设置Toast宽度为屏幕宽度
                    params.height = WindowManager.LayoutParams.WRAP_CONTENT; //设置高度
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        mToast.show();
    }

    /**
     * 反射字段
     * @param object 要反射的对象
     * @param fieldName 要反射的字段名称
     */
    private static Object getField(Object object, String fieldName)
            throws NoSuchFieldException, IllegalAccessException {
        Field field = object.getClass().getDeclaredField(fieldName);
        if (field != null) {
            field.setAccessible(true);
            return field.get(object);
        }
        return null;
    }

}

使用:

ClickToast.showToast(MainActivity.this, Toast.LENGTH_LONG);

动画:

style.xml

<style name="ClickToast" parent="@android:style/Animation.Toast">
        <item name="android:windowEnterAnimation">@anim/anim_clicktoast_in</item>
        <item name="android:windowExitAnimation">@anim/anim_clicktoast_out</item>
    </style>

anim_clicktoast_in.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- 进入动画 -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromYDelta="100"
        android:toYDelta="0"
        android:duration="200"
        />
</set>

anim_clicktoast_out.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- 出去动画 -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromYDelta="0"
        android:toYDelta="100"
        android:duration="200"
        />
</set>

这里写图片描述

猜你喜欢

转载自blog.csdn.net/fan7983377/article/details/79488903