Android Toast поверх Toast - нижний остается, когда верхний уходит - PullRequest
0 голосов
/ 23 сентября 2019

Мое приложение создает много тостов во многих местах, вызывая

Toast.makeText(getBaseContext(), "Blah", Toast.LENGTH_SHORT).show();

(хорошо, я использую идентификатор ресурса, а не строку).Все отлично работает на всех версиях Android от 4 до 7, которые я когда-либо использовал, но с Android 8.1.0, если второй всплывающий тост появляется до исчезновения первого, первый восстанавливается при исчезновении второго.Я предполагаю, что менеджер дисплея запоминает пиксели под тостом и восстанавливает их, когда тост уходит, но он недостаточно умен, чтобы справиться со стопкой тостов, поэтому второй «запоминает» изображение первого,и восстанавливает его вместо основной области окна.

Я могу обойти эту проблему, используя оболочку «makeToast», которая каждый раз помещает объект Toast в статическую переменную и вызывает .cancel() для старой перед .show() новый.Это окончательное решение или есть лучший путь?

private static Toast lastToast;
private static Context toastContext; // set in onCreate
public static void makeToast(int resId, int duration) {
    if (lastToast != null) lastToast.cancel();
    lastToast = Toast.makeText(toastContext, resId, duration);
    lastToast.show();
}

1 Ответ

0 голосов
/ 24 сентября 2019

Это исправило это для меня - я обернул Toast своим собственным классом, который cancel() является последним объектом, вызывающим show(), перед show() новым.Выглядит как массивный взлом, но он сделал свою работу и потребовал только изменения строк import android.widget.Toast в остальной части моего приложения.

package my.app.hacks;

import android.content.Context;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;    

public class Toast extends android.widget.Toast {
    public static final int LENGTH_SHORT = android.widget.Toast.LENGTH_SHORT;
    public static final int LENGTH_LONG = android.widget.Toast.LENGTH_LONG;

    private static Toast lastShown;

    public Toast(Context context) {
        super(context);
    }

    public void show() {
        if (lastShown != null) lastShown.cancel();
        super.show();
        lastShown = this;
    }

    public static Toast makeText(Context context, CharSequence text, int duration) {
        //
        // this is almost copy-n-pasted from android.widget.Toast.makeText()
        //
        Toast result = new Toast(context);

        LayoutInflater inflate = (LayoutInflater)
                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        // we can't directly access com.android.internal.R identifiers so use the public interface
        int layout = Resources.getSystem().getIdentifier("transient_notification", "layout", "android");
        View v = inflate.inflate(layout, null);
        int id = Resources.getSystem().getIdentifier("message", "id", "android");
        TextView tv = (TextView)v.findViewById(id);
        tv.setText(text);

        // the original code accesses private members here - again, we have to use the public interface
        result.setView(v);
        result.setDuration(duration);

        return result;
    }

    public static Toast makeText(Context context, int resId, int duration)
            throws Resources.NotFoundException {
        return makeText(context, context.getResources().getText(resId), duration);
    }

}
...