package com.gujin.toast;

import android.app.Application;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;

public class ToastUtil {
    private static final String TAG = "ToastUtil";
    private static boolean initialized;
    private static Context sContext;
    private static Mode sDefaultMode;
    private static Toast sToast;

    /**
     * Initialize the util.
     *
     * @param context The context to use.
     */
    public static void initialize(Context context) {
        initialize(context, Mode.NORMAL);
    }

    /**
     * Initialize the util with the mode from user.
     *
     * @param context The context to use.
     * @param mode    The default display mode tu use. Either{@link Mode#NORMAL} or {@link Mode#REPLACEABLE}
     */
    public static void initialize(Context context, Mode mode) {
        if (initialized) {
            Log.w(TAG, "Invalid initialize, ToastUtil is already initialized");
            return;
        }

        if (context == null) {
            throw new NullPointerException("context can not be null");
        }

        if (context instanceof Application) {
            sContext = context;
        } else {
            sContext = context.getApplicationContext();
        }

        if (mode == null) {
            sDefaultMode = Mode.NORMAL;
        } else {
            sDefaultMode = mode;
        }

        initialized = true;
    }

    /**
     * Display mode
     */
    public enum Mode {

        /**
         * Show as a normal toast. This mode could be user-definable.  This is the default.
         */
        NORMAL,

        /**
         * When the toast is shown to the user , the text will be replaced if call the show() method again.  This mode could be user-definable.
         */
        REPLACEABLE
    }

    private ToastUtil() {
    }

    /**
     * Shot a toast with the text form a resource.
     *
     * @param resId The resource id of the string resource to use.
     */
    public static void show(int resId) {
        show(sContext.getText(resId));
    }

    /**
     * Shot a toast.
     *
     * @param text The text to show.
     */
    public static void show(CharSequence text) {
        show(text, false);
    }

    /**
     * Shot a toast with the text form a resource.
     *
     * @param resId        The resource id of the string resource to use.
     * @param durationLong Whether the toast show for a long period of time?
     */
    public static void show(int resId, boolean durationLong) {
        show(sContext.getText(resId), durationLong);
    }

    /**
     * Show a toast.
     *
     * @param text         The text to show.
     * @param durationLong Whether the toast show for a long period of time?
     */
    public static void show(CharSequence text, boolean durationLong) {
        show(text, durationLong, sDefaultMode);
    }

    /**
     * Shot a toast with the text form a resource.
     *
     * @param resId The resource id of the string resource to use.
     * @param mode  The display mode to use.  Either {@link Mode#NORMAL} or {@link Mode#REPLACEABLE}
     */
    public static void show(int resId, Mode mode) {
        show(sContext.getText(resId), false, mode);
    }

    /**
     * Show a toast.
     *
     * @param text The text to show.
     * @param mode The display mode to use.  Either {@link Mode#NORMAL} or {@link Mode#REPLACEABLE}
     */
    public static void show(CharSequence text, Mode mode) {
        show(text, false, mode);
    }

    /**
     * Shot a toast with the text form a resource.
     *
     * @param resId        resId The resource id of the string resource to use.
     * @param durationLong Whether the toast show for a long period of time?
     * @param mode         The display mode to use.  Either {@link Mode#NORMAL} or {@link Mode#REPLACEABLE}
     */
    public static void show(int resId, boolean durationLong, Mode mode) {
        show(sContext.getText(resId), durationLong, mode);
    }

    /**
     * Show a toast.
     *
     * @param text         The text to show.
     * @param durationLong Whether the toast show for a long period of time?
     * @param mode         The display mode to use.  Either {@link Mode#NORMAL} or {@link Mode#REPLACEABLE}
     */
    public static void show(CharSequence text, boolean durationLong, Mode mode) {
        if (mode == Mode.NORMAL || mode == null) {
            Toast.makeText(sContext, text, durationLong ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT).show();
            return;
        }

        if (sToast == null) {
            sToast = Toast.makeText(sContext, text, durationLong ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT);
        } else {
            sToast.setText(text);
        }
        sToast.show();
    }
}

@@ -361,16 +361,50 @@
  sToast;
+%0A    private static int sDuration;
 %0A%0A    /*
@@ -1307,89 +1307,20 @@
     
-if (mode == null) %7B%0A            sDefaultMode = Mode.NORMAL;%0A        %7D else %7B%0A    
+// nullable%0A
     
@@ -1343,26 +1343,16 @@
  = mode;
-%0A        %7D
 %0A%0A      
@@ -4315,46 +4315,114 @@
    i
-f (mode == Mode.NORMAL %7C%7C 
+nt duration = durationLong ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT;%0A%0A        if (
 mode 
-== null
+!= Mode.REPLACEABLE
 ) %7B%0A
@@ -4476,53 +4476,8 @@
 tion
-Long ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT
 ).sh
@@ -4543,170 +4543,330 @@
 null
-) %7B%0A            sToast = Toast.makeText(sContext, text, durationLong ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT);%0A        %7D else %7B%0A            sToast.setText(text);
+ %7C%7C sDuration != duration) %7B%0A            sDuration = duration;%0A            sToast = Toast.makeText(sContext, text, duration);%0A        %7D else %7B%0A            try %7B%0A                sToast.setText(text);%0A            %7D catch (RuntimeException e) %7B%0A                sToast = Toast.makeText(sContext, text, duration);%0A            %7D
 %0A   

解决更换显示时长不生效的问题 解决 Toast.setText() 引发的 RuntimeException