Android Toast工具类无法取消堆叠Toast问题排查求助
问题根源:Java的参数传递特性
你遇到的问题核心在于Java是按值传递参数的,你的工具类方法initializeToast里的toast参数只是Activity中private Toast toast的一个副本。当你在方法里执行toast = Toast.makeText(...)时,只是修改了这个副本的引用,并没有改变Activity中原本的toast变量。
所以每次点击按钮时,Activity里的toast始终是null,调用cancelToast(toast)相当于什么都没做,旧的Toast自然不会被取消,新的Toast不断创建就导致了堆叠。
而之前把代码写在Activity内部时,你直接操作的是Activity成员变量toast,每次调用initToast都会更新这个成员变量的引用,所以旧的Toast能被正确取消。
解决方案:让工具类返回Toast实例,更新Activity中的引用
修改你的Utilities类,让initializeToast方法返回创建好的Toast,这样Activity就能更新自己的toast成员变量:
public class Utilities { public static Toast initializeToast(Context context, Toast toast, String res) { cancelToast(toast); Toast newToast = Toast.makeText(context, res, Toast.LENGTH_SHORT); newToast.show(); return newToast; } public static void cancelToast(Toast toast){ if (toast != null) { toast.cancel(); } } }
然后在Activity的点击事件里,更新toast变量:
button.setOnClickListener(view -> { if (TextUtils.isEmpty(mEditWordView.getText())) { toast = Utilities.initializeToast(this, toast, "Message Example"); } });
这样每次点击时,都会把当前显示的Toast(如果有的话)传递给工具类取消,然后把新创建的Toast赋值给Activity的toast成员变量,下次点击就能正确取消上一个Toast了。
另一种方案:使用可变容器传递Toast引用
如果你不想修改方法的返回值,也可以用一个长度为1的Toast数组作为参数(因为数组是引用类型,修改数组内的元素会影响外部):
public class Utilities { public static void initializeToast(Context context, Toast[] toastHolder, String res) { cancelToast(toastHolder[0]); toastHolder[0] = Toast.makeText(context, res, Toast.LENGTH_SHORT); toastHolder[0].show(); } public static void cancelToast(Toast toast){ if (toast != null) { toast.cancel(); } } }
Activity中使用时:
// 把成员变量改成数组 private Toast[] toastHolder = new Toast[1]; // 点击事件里 button.setOnClickListener(view -> { if (TextUtils.isEmpty(mEditWordView.getText())) { Utilities.initializeToast(this, toastHolder, "Message Example"); } });
这种方式也能让工具类更新外部的Toast引用,达到取消旧Toast的效果。
内容的提问来源于stack exchange,提问作者LA_Homie
相关产品推荐
相关产品推荐

