在自定义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>