package com.gianlu.commonutils.ui; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.util.Log; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import com.gianlu.commonutils.CommonUtils; import com.gianlu.commonutils.dialogs.DialogUtils; public final class Toaster { private final static Handler handler = new Handler(Looper.getMainLooper()); private static final String TAG = Toaster.class.getSimpleName(); private final Context context; private String msg; private int msgRes; private Object[] args; private Object extra; private boolean shown = false; private Toaster(@Nullable Context context) { this.context = context; } @NonNull public static Toaster with(@NonNull Context context) { return new Toaster(context); } @NonNull public static Toaster build() { return new Toaster(null); } public Toaster message(@StringRes int str, Object... args) { if (context != null) { this.msg = context.getString(str, args); this.msgRes = 0; this.args = null; } else { this.msgRes = str; this.args = args; this.msg = null; } return this; } public Toaster message(String str) { this.msg = str; this.msgRes = 0; this.args = null; return this; } public Toaster extra(Object extra) { this.extra = extra; return this; } public void show() { if (context == null) throw new IllegalStateException("Missing context instance!"); show(context); } public void show(@NonNull Context context) { if (shown) { if (CommonUtils.isDebug()) System.out.println("Skipping toast, already shown!"); return; } if (!DialogUtils.isContextValid(context)) { if (CommonUtils.isDebug()) System.out.println("Skipping toast, context is invalid: " + context); return; } if (msg == null) { if (msgRes != 0) { msg = context.getString(msgRes, args); msgRes = 0; args = null; } else { throw new IllegalArgumentException("Missing toast message!"); } } final int duration; if (msg.length() > 48) duration = Toast.LENGTH_LONG; else duration = Toast.LENGTH_SHORT; Runnable action = () -> { if (DialogUtils.isContextValid(context)) Toast.makeText(context, msg, duration).show(); }; if (Looper.myLooper() == Looper.getMainLooper()) action.run(); else handler.post(action); Log.v(TAG, buildLogMessage(context)); shown = true; } @NonNull private String buildLogMessage(@NonNull Context ctx) { return "Toaster{context=" + ctx + ", msg='" + msg + "', extra=" + extra + '}'; } @Override protected void finalize() throws Throwable { super.finalize(); if (!shown && CommonUtils.isDebug()) System.err.println("Leaked " + this); } }