Как избежать тоста, если будет показан один тост
У меня есть несколько SeekBar
и onSeekBarProgressStop()
, я хочу показать сообщение Toast
.
Но если на SeekBar
я выполняю действие быстро, тогда поток пользовательского интерфейса каким-то образом блокируется, а сообщение Toast
ожидает, пока поток пользовательского интерфейса будет свободен.
Теперь я беспокоюсь о том, чтобы избежать появления нового сообщения Toast
, если сообщение Toast
уже отображается. Или их любое условие, по которому мы проверяем, что поток пользовательского интерфейса в настоящее время свободен, тогда я покажу сообщение Toast
.
Я попробовал это в обоих направлениях, используя runOnUIThread()
, а также создав новый Handler
.
Ответы
Ответ 1
Я пробовал разные вещи, чтобы сделать это. Сначала я попытался использовать cancel()
, что не повлияло на меня (см. Также этот ответ).
С setDuration(n)
я тоже никуда не ходил. Оказалось, что он записывает getDuration()
, что он несет значение 0 (если параметр makeText()
был Toast.LENGTH_SHORT
) или 1 (если параметр makeText()
был Toast.LENGTH_LONG
).
Наконец, я попытался проверить, есть ли просмотр тоста isShown()
. Конечно, это не так, если нет тоста, но даже больше, он возвращает фатальную ошибку в этом случае. Поэтому мне нужно было попытаться поймать ошибку.
Теперь isShown()
возвращает true, если отображается тост.
Используя isShown()
, я придумал метод:
/**
* <strong>public void showAToast (String st)</strong></br>
* this little method displays a toast on the screen.</br>
* it checks if a toast is currently visible</br>
* if so </br>
* ... it "sets" the new text</br>
* else</br>
* ... it "makes" the new text</br>
* and "shows" either or
* @param st the string to be toasted
*/
public void showAToast (String st){ //"Toast toast" is declared in the class
try{ toast.getView().isShown(); // true if visible
toast.setText(st);
} catch (Exception e) { // invisible if exception
toast = Toast.makeText(theContext, st, toastDuration);
}
toast.show(); //finally display it
}
Ответ 2
Ниже приведено альтернативное решение наиболее популярного ответа без try/catch.
public void showAToast (String message){
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
mToast.show();
}
Ответ 3
Чистое решение, которое работает из коробки. Определите это в своей деятельности:
private Toast toast;
/**
* Use this to prevent multiple Toasts from spamming the UI for a long time.
*/
public void showToast(CharSequence text, int duration)
{
if (toast == null)
toast = Toast.makeText(this, text, duration);
else
toast.setText(text);
toast.show();
}
public void showToast(int resId, int duration)
{
showToast(getResources().getText(resId), duration);
}
Ответ 4
Усовершенствованная функция из вышеупомянутого потока, которая будет показывать тост, только если не отображается с тем же текстовым сообщением:
public void showSingleToast(){
try{
if(!toast.getView().isShown()) {
toast.show();
}
} catch (Exception exception) {
exception.printStackTrace();
Log.d(TAG,"Toast Exception is "+exception.getLocalizedMessage());
toast = Toast.makeText(this.getActivity(), getContext().getString(R.string.no_search_result_fou'enter code here'nd), Toast.LENGTH_SHORT);
toast.show();
}
}
Ответ 5
отслеживать последний раз, когда вы показывали тост, и повторно показывать его без-op, если он попадает в некоторый интервал.
public class RepeatSafeToast {
private static final int DURATION = 4000;
private static final Map<Object, Long> lastShown = new HashMap<Object, Long>();
private static boolean isRecent(Object obj) {
Long last = lastShown.get(obj);
if (last == null) {
return false;
}
long now = System.currentTimeMillis();
if (last + DURATION < now) {
return false;
}
return true;
}
public static synchronized void show(Context context, int resId) {
if (isRecent(resId)) {
return;
}
Toast.makeText(context, resId, Toast.LENGTH_LONG).show();
lastShown.put(resId, System.currentTimeMillis());
}
public static synchronized void show(Context context, String msg) {
if (isRecent(msg)) {
return;
}
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
lastShown.put(msg, System.currentTimeMillis());
}
}
а затем
RepeatSafeToast.show(this, "Hello, toast.");
RepeatSafeToast.show(this, "Hello, toast."); // won't be shown
RepeatSafeToast.show(this, "Hello, toast."); // won't be shown
RepeatSafeToast.show(this, "Hello, toast."); // won't be shown
это не идеально, так как длина LENGTH_SHORT
и LENGTH_LONG
undefined, но на практике она хорошо работает. он имеет преимущество перед другими решениями, которые вам не нужно удерживать на объекте Toast, а синтаксис вызова остается кратким.
Ответ 6
Комбинированное решение
В моем случае мне нужно было отменить текущий тост, если он показан, и отобразить другой.
Это должно было решить сценарий, когда пользователь запрашивает услугу, пока она по-прежнему загружается или недоступна. Мне нужно показать тост (возможно, меня будет отличаться, если запрашиваемая услуга отличается). В противном случае тосты будут отображаться по порядку, и для их автоматического скрытия потребуется очень много времени.
Итак, в основном я сохраняю экземпляр тоста, который я создаю, и следующий код: как его безопасно отменить
synchronized public void cancel() {
if(toast == null) {
Log.d(TAG, "cancel: toast is null (occurs first time only)" );
return;
}
final View view = toast.getView();
if(view == null){
Log.d(TAG, "cancel: view is null");
return;
}
if (view.isShown()) {
toast.cancel();
}else{
Log.d(TAG, "cancel: view is already dismissed");
}
}
И чтобы использовать его, я теперь не могу беспокоиться об отмене, как в:
if (toastSingleton != null ) {
toastSingleton.cancel();
toastSingleton.showToast(messageText);
}else{
Log.e(TAG, "setMessageText: toastSingleton is null");
}
showToast зависит от вас, как реализовать его, поскольку мне нужен пользовательский вид моего тоста.
Ответ 7
Хорошо для остановки укладки, например. клик под управлением тоста. Исходя из ответа @Addi.
public Toast toast = null;
//....
public void favsDisplay(MenuItem item)
{
if(toast == null) // first time around
{
Context context = getApplicationContext();
CharSequence text = "Some text...";
int duration = Toast.LENGTH_SHORT;
toast = Toast.makeText(context, text, duration);
}
try
{
if(toast.getView().isShown() == false) // if false not showing anymore, then show it
toast.show();
}
catch (Exception e)
{}
}
Ответ 8
Проверьте, отображается ли на экране тост-сообщение, отображается оно или нет. Для показа тостового сообщения сделайте отдельный класс. И используйте метод этого класса, который отображает тост-сообщение после проверки видимости тост-сообщения. Используйте этот фрагмент кода:
public class AppToast {
private static Toast toast;
public static void showToast(Context context, String message) {
try {
if (!toast.getView().isShown()) {
toast=Toast.makeText(context, message, Toast.LENGTH_SHORT);
toast.show();
}
} catch (Exception ex) {
toast=Toast.makeText(context,message,Toast.LENGTH_SHORT);
toast.show();
}
}
}
Я надеюсь, что это решение поможет вам.
Спасибо
Ответ 9
добавлен таймер для удаления тоста через 2 секунды.
private Toast toast;
public void showToast(String text){
try {
toast.getView().isShown();
toast.setText(text);
}catch (Exception e){
toast = Toast.makeText(mContext, text, Toast.LENGTH_SHORT);
}
if(toast.getView().isShown()){
new Timer().schedule(new TimerTask() {
@Override
public void run() {
toast.cancel();
}
}, 2000);
}else{
toast.show();
}
}
showToast("Please wait");
Ответ 10
Мое решение:
public class Utils {
public static Toast showToast(Context context, Toast toast, String str) {
if (toast != null)
toast.cancel();
Toast t = Toast.makeText(context, str, Toast.LENGTH_SHORT);
t.show();
return t;
}
}
и вызывающий должен иметь член Toast для этого параметра метода, или
class EasyToast {
Toast toast;
Context context;
public EasyToast(Context context) {
this.context = context;
}
public Toast show(String str) {
if (toast != null)
toast.cancel();
Toast t = Toast.makeText(context, str, Toast.LENGTH_SHORT);
t.show();
return t;
}
}
есть вспомогательный класс, как это.