全局Toast和Snackbar

在項目中遇到,圖片下載的方法封裝在imageUtils類中,下載要用Toast到提醒。如果在activity中可以用runOnUiThreadHandler來顯示提醒,現(xiàn)在不是在activity,又不想在imageUtils中用Handler。所以想到如果有個全局的Toast就方便多了。

先上效果圖:

Toast.gif

全局Toast:
1. 支持默認格式,自上向下布局為ImageView,TextView,TextView,三個控件可以自由組合顯示或隱藏
2. 支持Top,Center,Bottom的位置顯示
3. 支持多樣的顯示格式,可以傳入自定義的layout的View
4. 共用一個Toast對象,防止多次Toast重疊并顯示時間累加,該控件近保留最后一次的設置和顯示。
5. 最好在自定義的Application中new該Toast,Activity,F(xiàn)ragment,Adapter中都可以直接調(diào)用。

自定義Toast代碼如下, 用靜態(tài)內(nèi)部類Builder設置Toast的樣式:

public class FlexibleToast {

    public static final int GRAVITY_BOTTOM = 0;
    public static final int GRAVITY_CENTER = 1;
    public static final int GRAVITY_TOP = 2;
    public static final int TOAST_SHORT = 0;
    public static final int TOAST_LONG = 1;

    private Context mContext;

    private Toast flexibleToast;

    public void toastShow(Builder builder) {
        if (flexibleToast == null) {
            flexibleToast = new Toast(mContext);
        }
        // toast position
        if (builder.mGravity == GRAVITY_CENTER) {
            flexibleToast.setGravity(Gravity.CENTER | Gravity.CENTER_VERTICAL, 0, 0);
        } else if (builder.mGravity == GRAVITY_TOP) {
            flexibleToast.setGravity(Gravity.TOP | Gravity.CENTER_VERTICAL, 0, Tools.dip2px(mContext, 20));
        } else {
            flexibleToast.setGravity(Gravity.BOTTOM | Gravity.CENTER_VERTICAL, 0, Tools.dip2px(mContext, 20));
        }
        if (builder.mDuration == TOAST_LONG) {
            flexibleToast.setDuration(Toast.LENGTH_LONG);
        } else {
            flexibleToast.setDuration(Toast.LENGTH_SHORT);
        }
        if (builder.hasCustomerView && builder.mCustomerView != null) {
            flexibleToast.setView(builder.mCustomerView);
        } else {
            flexibleToast.setView(builder.mDefaultView);
        }
        flexibleToast.show();
    }

    public FlexibleToast(Context context) {
        mContext = context;
    }

    /**
     * 控制Toast的顯示樣式
     */
    public static class Builder {
        private View mDefaultView;
        private View mCustomerView;
        private ImageView mIvImage;
        private TextView mTvFirst;
        private TextView mTvSecond;

        private View dividerFirst;
        private View dividerSecond;

        private int mDuration = Toast.LENGTH_SHORT;// 0 short, 1 long
        private int mGravity = 0;
        private boolean hasCustomerView = false; // 是否使用自定義layout


        /**
         * 使用全局的ApplicationContext進行初始化
         * @param context
         */
        public Builder(Context context) {
            mDefaultView = LayoutInflater.from(context).inflate(R.layout.layout_toast_flexible, null);
            mIvImage = (ImageView) mDefaultView.findViewById(R.id.iv_img);
            mTvFirst = (TextView) mDefaultView.findViewById(R.id.tv_text_first);
            mTvSecond = (TextView) mDefaultView.findViewById(R.id.tv_text_second);
            dividerFirst = mDefaultView.findViewById(R.id.divider_first);
            dividerSecond = mDefaultView.findViewById(R.id.divider_second);
        }

        public Builder setImageResource(int resId) {
            this.mIvImage.setImageResource(resId);
            this.mIvImage.setVisibility(View.VISIBLE);
            this.dividerFirst.setVisibility(View.VISIBLE);
            return this;
        }

        public Builder setFirstText(String firstText) {
            this.mTvFirst.setText(firstText);
            this.mTvFirst.setVisibility(View.VISIBLE);
            this.dividerSecond.setVisibility(View.VISIBLE);
            return this;
        }

        public Builder setSecondText(String secondText) {
            this.mTvSecond.setText(secondText);
            this.mTvSecond.setVisibility(View.VISIBLE);
            return this;
        }

        public Builder setDuration(int duration) {
            this.mDuration = duration;
            return this;
        }

        public Builder setGravity(int gravity) {
            this.mGravity = gravity;
            return this;
        }

        /**
         * 為Toast指定自定義的layout,此時上面對ImageView和TextView的設置失效。
         * @param customerView
         * @return
         */
        public Builder setCustomerView(View customerView) {
            this.mCustomerView = customerView;
            this.hasCustomerView = true;
            return this;
        }
    }

}

在Application中初始化自定義Toast:
創(chuàng)建自定義ToastflexibleToast = new FlexibleToast(this),然后提供方法toastShowByBuilder()供調(diào)用傳builder設置樣式

public class BaseApp extends Application {
    // 全局的 handler 對象
    private final Handler appHandler = new Handler();
    // 全局的 Toast 對象
    private FlexibleToast flexibleToast;
    private static BaseApp instance;
    public static void setInstance(BaseApp instance) {
        BaseApp.instance = instance;
    }
    public static BaseApp getInstance() {
        return instance;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        setInstance(this);
        flexibleToast = new FlexibleToast(this);
        Log.i("TAG","主線程"+Thread.currentThread().getId());

    }
    public Handler getAppHandler() {
        return appHandler;
    }
    public void toastShowByBuilder(final FlexibleToast.Builder builder) {
        if (Looper.myLooper() != Looper.getMainLooper()) {
            getAppHandler().post(new Runnable() {
                @Override
                public void run() {
                    flexibleToast.toastShow(builder);
                }
            });
        } else {
            flexibleToast.toastShow(builder);
        }
    }
}

下面分別列出Toast在屏幕中間、子線程、自定義顯示的用法:

設置顯示位置在屏幕中間:

FlexibleToast.Builder builder = new FlexibleToast.Builder(MainActivity.this)
.setGravity(FlexibleToast.GRAVITY_CENTER)
.setFirstText("中間").setSecondText("提醒");
BaseApp.getInstance().toastShowByBuilder(builder);

在子線程顯示:

   new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Log.i("TAG","子線程");
                        FlexibleToast.Builder builder = new FlexibleToast.Builder(MainActivity.this)
                                .setGravity(FlexibleToast.GRAVITY_BOTTOM)
                                .setFirstText("底部").setSecondText("提醒");
                        BaseApp.getInstance().toastShowByBuilder(builder);
                    }
                }).start();

自定義樣式:

final View customview= LayoutInflater
                .from(this)
                .inflate(R.layout.item,null,false);

 FlexibleToast.Builder builder = new FlexibleToast.Builder(MainActivity.this)
                        .setGravity(FlexibleToast.GRAVITY_BOTTOM)
                        .setCustomerView(customview);
                BaseApp.getInstance().toastShowByBuilder(builder);

git上源代碼地址,歡迎指出錯誤哈!

SnackBar是 Android Support Library 22.2.0 里面新增提供的一個控件。SnackBar默認從屏幕底部彈出,像Toast一樣會自動消失,當然也可以手動劃出屏幕消失。Toast是不能交互的,而如果需要,SnackBar默認是可以添加一個點擊事件的。效果如下:

snackbar.gif

普通snackbar代碼如下:
snckbar可以設置回調(diào)setCallback(new Snackbar.Callback())顯示和取消分別處理,不知道snackbar的用法,請點擊
還在用Toast?試試Snackbar!

 Snackbar snackbar = Snackbar.make(button3,"normalSnackbar", LENGTH_LONG).setActionTextColor(getResources().getColor(R.color.white))
                    /*    .setCallback(new Snackbar.Callback() {
                    @Override
                    public void onDismissed(Snackbar snackbar, int event) {
                        super.onDismissed(snackbar, event);
                        FlexibleToast.Builder builder = new FlexibleToast.Builder(MainActivity.this)
                        .setGravity(FlexibleToast.GRAVITY_CENTER)
                        .setFirstText("回調(diào)dismiss");
                        BaseApp.getInstance().toastShowByBuilder(builder);
                    }

                    @Override
                    public void onShown(Snackbar snackbar) {
                        super.onShown(snackbar);
                        FlexibleToast.Builder builder = new FlexibleToast.Builder(MainActivity.this)
                        .setGravity(FlexibleToast.GRAVITY_CENTER).setFirstText("回調(diào)show");
                        BaseApp.getInstance().toastShowByBuilder(builder);
                    }
                })*/
                        .setAction("點擊", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        FlexibleToast.Builder builder = new FlexibleToast.Builder(MainActivity.this)
                      .setGravity(FlexibleToast.GRAVITY_CENTER).setFirstText("中間toast");
                        BaseApp.getInstance().toastShowByBuilder(builder);
                    }
                });
                snackbar.show();
         

自定義snackbar代碼如下:

Snackbar snackbar = Snackbar.make(findViewById(R.id.button4),"自定義",Snackbar.LENGTH_LONG);
                View view = snackbar.getView();
                ViewGroup.LayoutParams Params = view.getLayoutParams();
                view.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
                CoordinatorLayout.LayoutParams layoutParams = new CoordinatorLayout.LayoutParams(Params.width,Params.height);
                layoutParams.gravity = Gravity.TOP;
//                TODO 為什么設置居中沒反應
//                layoutParams.gravity = Gravity.CENTER;為什么設置居中沒反應

                view.setLayoutParams(layoutParams);
                view.setBackgroundColor(getResources().getColor(R.color.colorPrimary));


//                view.setAnimation();
                ImageView imageView = new ImageView(MainActivity.this);
                imageView.setLayoutParams(new ViewGroup.LayoutParams(100,100));
                imageView.setImageDrawable(getResources().getDrawable(R.drawable.lufei));
                Snackbar.SnackbarLayout snackbarLayout = (Snackbar.SnackbarLayout) view;
                snackbarLayout.setOrientation(LinearLayout.HORIZONTAL);
                snackbarLayout.addView(imageView);
                snackbar.setAction("點擊", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        FlexibleToast.Builder builder = new FlexibleToast.Builder(MainActivity.this).setGravity(FlexibleToast.GRAVITY_CENTER).setFirstText("自定義的snackbar");
                        BaseApp.getInstance().toastShowByBuilder(builder);
                    }
                }).show();

git上源代碼地址,歡迎指出錯誤哈!
想要設置snackbar劇中顯示layoutParams.gravity = Gravity.CENTER;居然沒有效果,不知道哪里出錯了,有哪個兄弟看到了能指出,不勝感激?。?!

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容