在平时开发中,为了提高用户体验,我们经常会使用Toast来提示一些重要信息,例如“网络不可用”、“输入不能为空”等,但相比大家都遇到过如下问题:多次点击按钮,界面会匀速弹出Toast,即使切换到其他页面也会弹出,用户体验很不好,这也是本人最近根据测试反馈在项目中优化Toast显示的一点心得记录,下面也针对这种问题,给出解决方案,希望对大家有参考意义:
1) 当前页面用一个全局的Toast对象,保证页面窗口只有一个Toast对象,而不是每次都showToast的时候都新创建的一个Toast对象,这样创建的多个Toast对象会依次排队显示,导致界面匀速地弹出Toast对象而显示Toast信息;同时通过判断用户是否连续快速的点击按钮来过滤一部分连续点击事件,下面是定义的Toast显示和Toast取消的管理方法:
/**
* 显示Toast
*
* @param msg
* @param duration
*/
private void showToast(String msg, int duration) {
//如果当前Toast正在显示,直接返回
if (isShowingToast) {
return;
}
//当Toast不存在时,通过makeText函数构造Toast对象
//否则,重用存在的Toast,直接通过setText函数显示内容
if (mToast == null) {
mToast = Toast.makeText(MainActivity.this, msg, duration);
mToast.setGravity(Gravity.CENTER, 0, 0);
} else {
mToast.setText(msg);
}
mToast.show();
//重置标志位
isShowingToast = true;
//通过Handler根据Duration的值发送延时消息更新isShowingToast标志位
//Toast.LENGTH_LONG:3500ms
//Toast.LENGTH_SHORT:2000ms
int delayTime = mToast.getDuration() == Toast.LENGTH_SHORT ? 2000 : 3500;
mHandler.sendEmptyMessageDelayed(0x001, delayTime);
}
/**
* 取消Toast显示
*/
private void cancelToast() {
if (mToast != null) {
mToast.cancel();
}
}
2) 利用Toast Duration显示长短的时间值(Toast.LENGTH_SHORT对应于2000ms,而Toast.LENGTH_LONG对应于3500ms,如上面代码所示),通过Handler+标志位的形式来控制Toast显示时间内只显示一个Toast的show请求:
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0x001:
//更新isShowToast标志位
isShowingToast = false;
break;
default:
break;
}
}
};
3) 在当前页面onDestroy()或onBackPress()的时候,取消Toast显示,防止页面退出时Toast窗口还在显示:
@Override
protected void onDestroy() {
super.onDestroy();
//防止内存泄漏
if (mHandler != null) {
mHandler.removeCallbacksAndMessages(null);
}
//取消Toast显示
cancelToast();
}
最后贴上页面完整代码:
package com.okg.toast;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button btnShowToast;
private Toast mToast = null;
private boolean isShowingToast = false;
private long mLastClickTime = 0L;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0x001:
//更新isShowToast标志位
isShowingToast = false;
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
btnShowToast = (Button) findViewById(R.id.btn_show);
btnShowToast.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isFastDoubleClick()) {
return;
}
showToast("show toast test");
}
});
}
private boolean isFastDoubleClick() {
return isFastDoubleClick(500);
}
private boolean isFastDoubleClick(long timeGap) {
boolean isFastDoubleClick = false;
//获取当前时间
long currTime = System.currentTimeMillis();
if ((currTime - mLastClickTime) < timeGap) {
isFastDoubleClick = true;
} else {
mLastClickTime = currTime;
}
return isFastDoubleClick;
}
/**
* 显示Toast
*
* @param msg
*/
private void showToast(String msg) {
showToast(msg, Toast.LENGTH_SHORT);
}
/**
* 显示Toast
*
* @param msg
* @param duration
*/
private void showToast(String msg, int duration) {
//如果当前Toast正在显示,直接返回
if (isShowingToast) {
return;
}
//当Toast不存在时,通过makeText函数构造Toast对象
//否则,重用存在的Toast,直接通过setText函数显示内容
if (mToast == null) {
mToast = Toast.makeText(MainActivity.this, msg, duration);
mToast.setGravity(Gravity.CENTER, 0, 0);
} else {
mToast.setText(msg);
}
mToast.show();
//重置标志位
isShowingToast = true;
//通过Handler根据Duration的值发送延时消息更新isShowingToast标志位
//Toast.LENGTH_LONG:3500ms
//Toast.LENGTH_SHORT:2000ms
int delayTime = mToast.getDuration() == Toast.LENGTH_SHORT ? 2000 : 3500;
mHandler.sendEmptyMessageDelayed(0x001, delayTime);
}
/**
* 取消Toast显示
*/
private void cancelToast() {
if (mToast != null) {
mToast.cancel();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//防止内存泄漏
if (mHandler != null) {
mHandler.removeCallbacksAndMessages(null);
}
//取消Toast显示
cancelToast();
}
}