Android中用Toast.cancel()方法优化toast内容的显示

文章介绍了一个自定义Toast类的方法,用于解决Android应用中Toast显示队列问题,通过同步机制确保每个Toast内容正确显示。代码示例展示了如何实现并使用此功能。
AI助手已提取文章相关产品:
产品在测试过程中发现一个bug,就是测试人员不停的疯狂的点击某个按钮,触发了toast以后,toast内容会一直排着队的显示出来,不能很快的消失。这样可能会影响用户的使用。

看到Toast有一个cancel()方法:


<table id="pubmethods" class="jd-sumtable " style="border-bottom: rgb(211,211,211) 0px dotted; border-left: rgb(211,211,211) 0px dotted; padding-bottom: 0px; margin: 0px 0px 1em 1em; padding-left: 0px; width: 933px; padding-right: 0px; border-collapse: collapse; font-family: arial,sans-serif; color: rgb(51,51,51); font-size: 0.9em; border-top: rgb(211,211,211) 0px dotted; border-right: rgb(211,211,211) 0px dotted; padding-top: 0px;"><tbody style="padding-bottom: 0px; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px;"><tr class="alt-color api apilevel-1" style="padding-bottom: 0px; border-right-width: 0px; background-color: rgb(246,246,246); margin: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px;">
<td class="jd-typecol" style="text-align: right; padding-bottom: 6px; margin: 0px; padding-left: 12px; padding-right: 12px; vertical-align: top; padding-top: 6px;">
<nobr>void</nobr></td>
<td class="jd-linkcol" width="100%" style="text-align: left; padding-bottom: 6px; margin: 0px; padding-left: 12px; padding-right: 12px; vertical-align: top; padding-top: 6px;">
<nobr><span class="sympad" style="margin-right:2px"><a href="file:///D:/Program%20Files/Android/android-sdk/docs/reference/android/widget/Toast.html#cancel()" style="color:rgb(0,102,153); text-decoration:none">cancel</a></span>()</nobr><div class="jd-descrdiv" style="padding-bottom: 0px; border-right-width: 0px; margin: 0px; padding-left: 1em; padding-right: 1em; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 3px;">
Close the view if it's showing, or don't show it if it isn't showing yet.
</td>
</tr></tbody></table>
做程序员的,基本一看api就知道,用这个可以取消上一个toast的显示,然后显示下一个,这样就能解决出现的问题。可是在测试的过程中,发现却没有想象中的那么简单,不信可以百度一下,很多很多人发现toast的cancel()方法不起作用。还是不讲具体过程,只讲结果吧。
我把toast做成了一个应用类,方便使用,大家可以直接用:


<textarea readonly name="code" class="java">package com.arui.framework.android.util;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;
</textarea><textarea readonly name="code" class="java">/**
* Toast util class.
*
* @author [url=http://blog.youkuaiyun.com/arui319]http://blog.youkuaiyun.com/arui319[/url]
* @version 2011/11/30
*
*/
public class ToastUtil {

private static Handler handler = new Handler(Looper.getMainLooper());

private static Toast toast = null;

private static Object synObj = new Object();

public static void showMessage(final Context act, final String msg) {
showMessage(act, msg, Toast.LENGTH_SHORT);
}

public static void showMessage(final Context act, final int msg) {
showMessage(act, msg, Toast.LENGTH_SHORT);
}

public static void showMessage(final Context act, final String msg,
final int len) {
new Thread(new Runnable() {
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
synchronized (synObj) {
if (toast != null) {
toast.cancel();
toast.setText(msg);
toast.setDuration(len);
} else {
toast = Toast.makeText(act, msg, len);
}
toast.show();
}
}
});
}
}).start();
}


public static void showMessage(final Context act, final int msg,
final int len) {
new Thread(new Runnable() {
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
synchronized (synObj) {
if (toast != null) {
toast.cancel();
toast.setText(msg);
toast.setDuration(len);
} else {
toast = Toast.makeText(act, msg, len);
}
toast.show();
}
}
});
}
}).start();
}

}
</textarea><br>

<br>
代码的逻辑很简单。这里加了同步,这样做可以确保每一个toast的内容至少可以显示出来,而不是还没显示就取消掉了。这样做,是因为toast的内容不一定完全相同,如果没显示出来,也会有问题。<br>


<br>

---------------------------------------------------------------------------

[b]GL(arui319) [/b]

[b]http://blog.youkuaiyun.com/arui319[/b]

[b]<本文可以转载,但是请保留以上作者信息。谢谢。>[/b]

---------------------------------------------------------------------------

您可能感兴趣的与本文相关内容

<template> <view class="teamPage"> <view class="teamPageTopBottom"> <view class="teamPageTopBottomTop flex-row-sb"> <u--input class="search-input" clearable placeholder="请输入客户的姓名" prefixIcon="search" prefixIconStyle="font-size: 22px;color: #909399;" v-model="query.name" @change="handleSearch" ></u--input> </view> <view class="statisticsNew"> <view class="flex-row-center statisticsTop"> <view :class="{ statisticsTopItem: true, statisticsTopItemActive: customerType == item.id, 'second-item-border': item.id == 1, 'second-border': item.id == 3, }" v-for="item in customerTypeList" :key="item.id" @click="handleChangeCpdType(item.id)" > <view>{{ item.name }}</view> </view> </view> </view> </view> <scroll-view class="teamPage__con" scroll-y="true" @scrolltolower="handleScrollToLower" > <view class="container"> <!-- 统计文本 --> <view class="total-text">共{{ listData.records.length }}人</view> <!-- 列表项 --> <view class="list-item" v-for="item in listData.records" :key="item.serialNo" > <view class="info" @click="customerType === 1 ? handleClick(item) : null" > <view>{{ item.customerName }}</view> <view style="margin-left: 30rpx"> {{ item.gender == 1 ? "男" : "女" }} </view> <view style="margin-left: 30rpx">{{ item.birthDate }}</view> <view> </view> </view> <template v-if="customerType == 1 || customerType == 2"> <view> <view> <!-- #ifdef H5 --> <img class="file-icon" :src="iconPdfimg" alt="" srcset=""> <!-- #endif --> <!-- #ifndef H5 --> <image class="file-icon" :src="iconPdfimg" mode="widthFix" ></image> <!-- #endif --> </view> <text class="file-name"> 客戶協議書</text> </view> <view style="margin-left: 10px"> <view> <!-- #ifdef H5 --> <img class="file-icon" :src="iconPdfimg" alt="" srcset=""> <!-- #endif --> <!-- #ifndef H5 --> <image class="file-icon" :src="iconPdfimg" mode="widthFix" ></image> <!-- #endif --> </view> <text class="file-name"> 客戶協議書</text> </view> </template> </view> <u-button class="primary" @click="handleConfirm" v-show="customerType == 2" >確認簽署</u-button > </view> <load-more :loading_status="loading_status"></load-more> </scroll-view> <drawing bgColor="#ffffff" :show="showDrawing" :needRotate="true" @cancel="showDrawing = false" @confirm="confirmSignature" ></drawing> </view> </template> <script> import loadMore from "@/components/loadMore/loadMore.vue"; // 引入loadMore组件 import drawing from "@/components/drawing/drawing.vue"; import CustomerPreview from "@/components/customerPreview"; import iconPdfimg from "@/static/image/icon-pdf2.png"; //引入图片 export default { name: "team", components: { loadMore, CustomerPreview, drawing, }, data() { return { query: { name: "", pageNum: 1, pageSize: 2000, }, iconPdfimg, customerType: 1, customerTypeList: [ { name: "客户待签署", id: 1, }, { name: "客户已签署", id: 2, }, { name: "已完成", id: 3, }, ], listData: { records: [], total: 0, }, infoData: { file: { fileSize: "1243", fileUrl: "", }, }, infoNumber: { file: { fileSize: "1243", fileUrl: "", }, }, infoList: { file: { fileSize: "1243", fileUrl: "", }, }, loading_status: "", // 初始化加载状态 timer: null, // 初始化timer showDrawing: false, //确认签署 }; }, onLoad(option) { this.customerType = option.customerType ? Number(option.customerType) : 1; this.getList(); }, methods: { async confirmSignature(url, needRotate) { //确认签署页面 this.showDrawing = false; const { data } = await uni.$u.http.get( "app/policy/serve/ifaTransferSign", { params: { sign: url, }, } ); uni.$u.toast("签署成功"); this.customerType = 3; this.loading_status = ""; this.getList(); // uni.navigateTo({ // url: "/pages/policyAssignment/policyServicer?customerType=3", // }); }, // 客户签署协议 async getFilelCustomer() { const { data } = await uni.$u.http.get("/app/policy/serve/preview", { params: { type: 1, serialNo: this.serialNo }, }); this.infoData.file.fileUrl = data; }, // 客户声明 async getFilel() { const { data } = await uni.$u.http.get("/app/policy/serve/preview", { params: { type: 2, serialNo: this.serialNo }, }); this.infoNumber.file.fileUrl = data; }, // 1.列表接口 async getList() { let { loading_status } = this; if (loading_status === "loading" || loading_status === "nomore") { return; } this.loading_status = "loading"; try { const { data } = await uni.$u.http.get( "/app/policy/serve/transferList", { params: { pageNum: "1", pageSize: "2000", status: this.customerType, search: this.query.name, }, } ); // 逐个更新属性,保持响应式 this.listData.records = data.records || []; this.listData.total = data.total || 0; this.listData.records.forEach((item) => { this.infoList.file.fileUrl = item.customerAgreement; }); console.log("3333333333", this.infoList.file.fileUrl); this.serialNo = (this.listData.records[0] || {}).serialNo; if (this.listData.records.length === 0) { this.loading_status = "none"; } else if (this.listData.total > this.listData.records.length) { this.loading_status = "hasLoading"; } else { this.loading_status = "nomore"; } if (this.listData.records.length > 0) { // this.getFilelCustomer(); // this.getFilel(); } } catch (error) { // 接口报错时也重置加载状态 // this.loading_status = "none"; console.error("获取数据失败:", error); } }, // 2.滚动到底部加载更多 // handleScrollToLower() { // if (this.loading_status == "hasLoading") { // this.query.pageNum++; // this.getList(); // } else { // this.loading_status = "nomore"; // } // }, // 搜索 handleSearch() { this.loading_status = ""; this.getList(); }, // tab栏切换 handleChangeCpdType(val) { this.customerType = val; this.loading_status = ""; this.listData.records = [] this.getList(); }, // handleClick(item) { // uni.navigateTo({ // url: `/pages/policyAssignment/customerSignature?id=${encodeURIComponent( // item.serialNo // )}`, // }); // }, handleConfirm() { //确认签署页面 this.showDrawing = true; }, }, }; </script> <style lang="scss" scoped> .teamPage { padding: 50rpx; min-height: 100vh; background: #f3f5f8; } .search-input { border: none; background: #fff; height: 90rpx; border-radius: 10rpx; } ::v-deep .u-input { position: relative; } ::v-deep .u-input__content { padding-left: 0 !important; justify-content: flex-start !important; } // 强制输入框居中 ::v-deep .u-input__inner { position: absolute !important; left: 50% !important; transform: translateX(-50%) !important; text-align: center !important; padding-left: 40rpx !important; } ::v-deep .u-input__prefix-icon { position: absolute !important; left: 30rpx !important; z-index: 10 !important; } // 确保占位符居中 ::v-deep .u-input__inner::placeholder { text-align: center !important; } // tab 栏 .statisticsNew { .statisticsTop { width: 73%; margin-top: 30rpx; border: 1px solid #05c4c8; border-radius: 10rpx; font-size: 28rpx; color: #05c4c8; } .statisticsTopItem { flex: 1; display: flex; justify-content: center; align-content: center; align-items: center; padding: 10rpx 0; } .statisticsTopItem { flex: 1; display: flex; justify-content: center; align-content: center; align-items: center; padding: 10rpx 0; } .statisticsTopItemActive { background: #05c4c8; color: #fff; } .second-item-border { border-right: 1px solid #05c4c8; border-radius: 10rpx; } .second-border { border-left: 1px solid #05c4c8; border-radius: 10rpx; } } .container { margin-top: 30rpx; .total-text { font-size: 32rpx; color: #333; margin-bottom: 15rpx; } .list-item { display: flex; flex-direction: row; justify-content: space-between; align-items: center; background-color: #fff; border-radius: 10rpx; margin-bottom: 25rpx; box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.1); } .info { display: flex; padding: 40rpx; width: 80%; } .info view { font-size: 28rpx; color: #333; line-height: 40rpx; } .pdf-icon { width: 40rpx; height: auto; } } .primary { width: 80%; position: fixed; bottom: 60rpx; left: 50%; transform: translateX(-50%); padding: 20rpx 32rpx; z-index: 100; font-size: 28rpx; border-radius: 10rpx; } .teamPage__con { max-height: 70vh; margin: 0 auto; } // 文件样式 .preview { margin-left: 20px; width: 80rpx; height: 70rpx; background: #fff; } ::v-deep .fileItem uni-image > div, ::v-deep .fileItem uni-image > img { width: 55%; height: 50%; object-fit: cover; border-radius: 8rpx; } .file-icon { width: 100rpx; height: 90rpx !important; } .file-name { font-size: 20rpx; } </style> 优化一下代码
最新发布
09-29
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值