全局Toast和Snackbar

作者: 翻身不做咸鱼 | 来源:发表于2016-08-30 23:32 被阅读1444次

    在项目中遇到,图片下载的方法封装在imageUtils类中,下载要用Toast到提醒。如果在activity中可以用runOnUiThreadHandler来显示提醒,现在不是在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,Fragment,Adapter中都可以直接调用。

    自定义Toast代码如下, 用静态内部类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:
    创建自定义ToastflexibleToast = new FlexibleToast(this),然后提供方法toastShowByBuilder()供调用传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可以设置回调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("回调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("回调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;居然没有效果,不知道哪里出错了,有哪个兄弟看到了能指出,不胜感激!!!

    相关文章

      网友评论

        本文标题:全局Toast和Snackbar

        本文链接:https://www.haomeiwen.com/subject/cwlfettx.html