Material Design 下的Toast 拓展 Snackbar

来源:互联网 发布:人工智能a7论坛 编辑:程序博客网 时间:2024/05/16 02:37


前些天看到一个类似 Toast 的提示效果的 控件,以前没用过,今天整理一下。

Snackbar 是介于Toast  和Dialog 之间的一种用户交互提示。但是查看源码,发现不能继承重写该类,不能自定义布局 ,甚至不能改变背景颜色,不知道这样设计的目的是什么。

下面介绍一下使用:

在 gradle 中添加    

compile 'com.android.support:design:23.0.0' 

导入 依赖包


简答使用:


     Snackbar.make(v, "Snackbar", Snackbar.LENGTH_LONG).show();

只简单的显示。与用户进行交互需要再添加 setAction()方法。


     Snackbar.make(v, "Snackbar", Snackbar.LENGTH_LONG).setAction("Click", new View.OnClickListener() {                    @Override                    public void onClick(View v) {                        Log.i("","");                    }                });

 Snackbar 提供了 交互按钮字体颜色的方法,没有提供 提示文字的颜色方法,默认的为白色字体 setActionTextColor


 Snackbar.make(v, "Snackbar", Snackbar.LENGTH_LONG).setActionTextColor(0xffff0000).                        setAction("Click", new View.OnClickListener() {                    @Override                    public void onClick(View v) {                        Log.i("","");                    }                }).show();


   红色框里面的为 用户可以点击的按钮

 虽然没有提供 提示语修改颜色的方法,但可以通过Html 加载的方式去改变字体颜色。效果如下


 StringBuilder stringBuilder = new StringBuilder();                double balance =332;                stringBuilder.append("剩余金额:"+"<font color=\"#fe5050\">" + balance                        + "</font>"+"元");                Snackbar.make(v, "", Snackbar.LENGTH_LONG).setText(Html.fromHtml(stringBuilder.toString())).                        setActionTextColor(Color.parseColor("#ffff00")).                        setDuration(Snackbar.LENGTH_INDEFINITE). //   设置这个值不会自动消失                        setAction("retry", new View.OnClickListener() {                    @Override                    public void onClick(View v) {                        Toast.makeText(MainActivity.this, "Click", Toast.LENGTH_LONG);                    }                }).show();




 还需要注意的是 activity需要继承AppCompatActivity。

SnackBar 源码:

//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)//package android.support.design.widget;import android.content.Context;import android.content.res.ColorStateList;import android.content.res.TypedArray;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.os.Build.VERSION;import android.os.Handler.Callback;import android.support.annotation.Nullable;import android.support.annotation.StringRes;import android.support.design.R.anim;import android.support.design.R.dimen;import android.support.design.R.id;import android.support.design.R.layout;import android.support.design.R.styleable;import android.support.design.widget.AnimationUtils;import android.support.design.widget.CoordinatorLayout;import android.support.design.widget.SnackbarManager;import android.support.design.widget.SwipeDismissBehavior;import android.support.design.widget.SwipeDismissBehavior.OnDismissListener;import android.support.v4.view.ViewCompat;import android.support.v4.view.ViewPropertyAnimatorListenerAdapter;import android.text.TextUtils;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.ViewParent;import android.view.View.MeasureSpec;import android.view.View.OnClickListener;import android.view.ViewGroup.LayoutParams;import android.view.animation.Animation;import android.view.animation.Animation.AnimationListener;import android.widget.FrameLayout;import android.widget.LinearLayout;import android.widget.TextView;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;public class Snackbar {    public static final int LENGTH_INDEFINITE = -2;    public static final int LENGTH_SHORT = -1;    public static final int LENGTH_LONG = 0;    private static final int ANIMATION_DURATION = 250;    private static final int ANIMATION_FADE_DURATION = 180;    private static final Handler sHandler = new Handler(Looper.getMainLooper(), new Callback() {        public boolean handleMessage(Message message) {            switch(message.what) {            case 0:                ((Snackbar)message.obj).showView();                return true;            case 1:                ((Snackbar)message.obj).hideView();                return true;            default:                return false;            }        }    });    private static final int MSG_SHOW = 0;    private static final int MSG_DISMISS = 1;    private final ViewGroup mParent;    private final Context mContext;    private final Snackbar.SnackbarLayout mView;    private int mDuration;    private final android.support.design.widget.SnackbarManager.Callback mManagerCallback = new android.support.design.widget.SnackbarManager.Callback() {        public void show() {            Snackbar.sHandler.sendMessage(Snackbar.sHandler.obtainMessage(0, Snackbar.this));        }        public void dismiss() {            Snackbar.sHandler.sendMessage(Snackbar.sHandler.obtainMessage(1, Snackbar.this));        }    };    Snackbar(ViewGroup parent) {        this.mParent = parent;        this.mContext = parent.getContext();        LayoutInflater inflater = LayoutInflater.from(this.mContext);        this.mView = (Snackbar.SnackbarLayout)inflater.inflate(layout.layout_snackbar, this.mParent, false);    }    public static Snackbar make(View view, CharSequence text, int duration) {        Snackbar snackbar = new Snackbar(findSuitableParent(view));        snackbar.setText(text);        snackbar.setDuration(duration);        return snackbar;    }    public static Snackbar make(View view, int resId, int duration) {        return make(view, view.getResources().getText(resId), duration);    }    @Nullable    private static ViewGroup findSuitableParent(View view) {        ViewGroup fallback = null;        do {            if(view instanceof CoordinatorLayout) {                return (ViewGroup)view;            }            if(view instanceof FrameLayout) {                if(view.getId() == 16908290) {                    return (ViewGroup)view;                }                fallback = (ViewGroup)view;            }            if(view != null) {                ViewParent parent = view.getParent();                view = parent instanceof View?(View)parent:null;            }        } while(view != null);        return fallback;    }    public Snackbar setAction(@StringRes int resId, OnClickListener listener) {        return this.setAction(this.mContext.getText(resId), listener);    }    public Snackbar setAction(CharSequence text, final OnClickListener listener) {        TextView tv = this.mView.getActionView();        if(!TextUtils.isEmpty(text) && listener != null) {            tv.setVisibility(0);            tv.setText(text);            tv.setOnClickListener(new OnClickListener() {                public void onClick(View view) {                    listener.onClick(view);                    Snackbar.this.dismiss();                }            });        } else {            tv.setVisibility(8);            tv.setOnClickListener((OnClickListener)null);        }        return this;    }    public Snackbar setActionTextColor(ColorStateList colors) {        TextView tv = this.mView.getActionView();        tv.setTextColor(colors);        return this;    }    public Snackbar setActionTextColor(int color) {        TextView tv = this.mView.getActionView();        tv.setTextColor(color);        return this;    }    public Snackbar setText(CharSequence message) {        TextView tv = this.mView.getMessageView();        tv.setText(message);        return this;    }    public Snackbar setText(@StringRes int resId) {        return this.setText(this.mContext.getText(resId));    }    public Snackbar setDuration(int duration) {        this.mDuration = duration;        return this;    }    public int getDuration() {        return this.mDuration;    }    public View getView() {        return this.mView;    }    public void show() {        SnackbarManager.getInstance().show(this.mDuration, this.mManagerCallback);    }    public void dismiss() {        SnackbarManager.getInstance().dismiss(this.mManagerCallback);    }    final void showView() {        if(this.mView.getParent() == null) {            LayoutParams lp = this.mView.getLayoutParams();            if(lp instanceof android.support.design.widget.CoordinatorLayout.LayoutParams) {                Snackbar.Behavior behavior = new Snackbar.Behavior();                behavior.setStartAlphaSwipeDistance(0.1F);                behavior.setEndAlphaSwipeDistance(0.6F);                behavior.setSwipeDirection(0);                behavior.setListener(new OnDismissListener() {                    public void onDismiss(View view) {                        Snackbar.this.dismiss();                    }                    public void onDragStateChanged(int state) {                        switch(state) {                        case 0:                            SnackbarManager.getInstance().restoreTimeout(Snackbar.this.mManagerCallback);                            break;                        case 1:                        case 2:                            SnackbarManager.getInstance().cancelTimeout(Snackbar.this.mManagerCallback);                        }                    }                });                ((android.support.design.widget.CoordinatorLayout.LayoutParams)lp).setBehavior(behavior);            }            this.mParent.addView(this.mView);        }        if(ViewCompat.isLaidOut(this.mView)) {            this.animateViewIn();        } else {            this.mView.setOnLayoutChangeListener(new Snackbar.SnackbarLayout.OnLayoutChangeListener() {                public void onLayoutChange(View view, int left, int top, int right, int bottom) {                    Snackbar.this.animateViewIn();                    Snackbar.this.mView.setOnLayoutChangeListener((Snackbar.SnackbarLayout.OnLayoutChangeListener)null);                }            });        }    }    private void animateViewIn() {        if(VERSION.SDK_INT >= 14) {            ViewCompat.setTranslationY(this.mView, (float)this.mView.getHeight());            ViewCompat.animate(this.mView).translationY(0.0F).setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR).setDuration(250L).setListener(new ViewPropertyAnimatorListenerAdapter() {                public void onAnimationStart(View view) {                    Snackbar.this.mView.animateChildrenIn(70, 180);                }                public void onAnimationEnd(View view) {                    SnackbarManager.getInstance().onShown(Snackbar.this.mManagerCallback);                }            }).start();        } else {            Animation anim = android.view.animation.AnimationUtils.loadAnimation(this.mView.getContext(), anim.snackbar_in);            anim.setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR);            anim.setDuration(250L);            anim.setAnimationListener(new AnimationListener() {                public void onAnimationEnd(Animation animation) {                    SnackbarManager.getInstance().onShown(Snackbar.this.mManagerCallback);                }                public void onAnimationStart(Animation animation) {                }                public void onAnimationRepeat(Animation animation) {                }            });            this.mView.startAnimation(anim);        }    }    private void animateViewOut() {        if(VERSION.SDK_INT >= 14) {            ViewCompat.animate(this.mView).translationY((float)this.mView.getHeight()).setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR).setDuration(250L).setListener(new ViewPropertyAnimatorListenerAdapter() {                public void onAnimationStart(View view) {                    Snackbar.this.mView.animateChildrenOut(0, 180);                }                public void onAnimationEnd(View view) {                    Snackbar.this.onViewHidden();                }            }).start();        } else {            Animation anim = android.view.animation.AnimationUtils.loadAnimation(this.mView.getContext(), anim.snackbar_out);            anim.setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR);            anim.setDuration(250L);            anim.setAnimationListener(new AnimationListener() {                public void onAnimationEnd(Animation animation) {                    Snackbar.this.onViewHidden();                }                public void onAnimationStart(Animation animation) {                }                public void onAnimationRepeat(Animation animation) {                }            });            this.mView.startAnimation(anim);        }    }    final void hideView() {        if(this.mView.getVisibility() == 0 && !this.isBeingDragged()) {            this.animateViewOut();        } else {            this.onViewHidden();        }    }    private void onViewHidden() {        this.mParent.removeView(this.mView);        SnackbarManager.getInstance().onDismissed(this.mManagerCallback);    }    private boolean isBeingDragged() {        LayoutParams lp = this.mView.getLayoutParams();        if(lp instanceof android.support.design.widget.CoordinatorLayout.LayoutParams) {            android.support.design.widget.CoordinatorLayout.LayoutParams cllp = (android.support.design.widget.CoordinatorLayout.LayoutParams)lp;            android.support.design.widget.CoordinatorLayout.Behavior behavior = cllp.getBehavior();            if(behavior instanceof SwipeDismissBehavior) {                return ((SwipeDismissBehavior)behavior).getDragState() != 0;            }        }        return false;    }    final class Behavior extends SwipeDismissBehavior<Snackbar.SnackbarLayout> {        Behavior() {        }        public boolean onInterceptTouchEvent(CoordinatorLayout parent, Snackbar.SnackbarLayout child, MotionEvent event) {            if(parent.isPointInChildBounds(child, (int)event.getX(), (int)event.getY())) {                switch(event.getActionMasked()) {                case 0:                    SnackbarManager.getInstance().cancelTimeout(Snackbar.this.mManagerCallback);                    break;                case 1:                case 3:                    SnackbarManager.getInstance().restoreTimeout(Snackbar.this.mManagerCallback);                case 2:                }            }            return super.onInterceptTouchEvent(parent, child, event);        }    }    public static class SnackbarLayout extends LinearLayout {        private TextView mMessageView;        private TextView mActionView;        private int mMaxWidth;        private int mMaxInlineActionWidth;        private Snackbar.SnackbarLayout.OnLayoutChangeListener mOnLayoutChangeListener;        public SnackbarLayout(Context context) {            this(context, (AttributeSet)null);        }        public SnackbarLayout(Context context, AttributeSet attrs) {            super(context, attrs);            TypedArray a = context.obtainStyledAttributes(attrs, styleable.SnackbarLayout);            this.mMaxWidth = a.getDimensionPixelSize(styleable.SnackbarLayout_android_maxWidth, -1);            this.mMaxInlineActionWidth = a.getDimensionPixelSize(styleable.SnackbarLayout_maxActionInlineWidth, -1);            if(a.hasValue(styleable.SnackbarLayout_elevation)) {                ViewCompat.setElevation(this, (float)a.getDimensionPixelSize(styleable.SnackbarLayout_elevation, 0));            }            a.recycle();            this.setClickable(true);            LayoutInflater.from(context).inflate(layout.layout_snackbar_include, this);        }        protected void onFinishInflate() {            super.onFinishInflate();            this.mMessageView = (TextView)this.findViewById(id.snackbar_text);            this.mActionView = (TextView)this.findViewById(id.snackbar_action);        }        TextView getMessageView() {            return this.mMessageView;        }        TextView getActionView() {            return this.mActionView;        }        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {            super.onMeasure(widthMeasureSpec, heightMeasureSpec);            if(this.mMaxWidth > 0 && this.getMeasuredWidth() > this.mMaxWidth) {                widthMeasureSpec = MeasureSpec.makeMeasureSpec(this.mMaxWidth, 1073741824);                super.onMeasure(widthMeasureSpec, heightMeasureSpec);            }            int multiLineVPadding = this.getResources().getDimensionPixelSize(dimen.snackbar_padding_vertical_2lines);            int singleLineVPadding = this.getResources().getDimensionPixelSize(dimen.snackbar_padding_vertical);            boolean isMultiLine = this.mMessageView.getLayout().getLineCount() > 1;            boolean remeasure = false;            if(isMultiLine && this.mMaxInlineActionWidth > 0 && this.mActionView.getMeasuredWidth() > this.mMaxInlineActionWidth) {                if(this.updateViewsWithinLayout(1, multiLineVPadding, multiLineVPadding - singleLineVPadding)) {                    remeasure = true;                }            } else {                int messagePadding = isMultiLine?multiLineVPadding:singleLineVPadding;                if(this.updateViewsWithinLayout(0, messagePadding, messagePadding)) {                    remeasure = true;                }            }            if(remeasure) {                super.onMeasure(widthMeasureSpec, heightMeasureSpec);            }        }        void animateChildrenIn(int delay, int duration) {            ViewCompat.setAlpha(this.mMessageView, 0.0F);            ViewCompat.animate(this.mMessageView).alpha(1.0F).setDuration((long)duration).setStartDelay((long)delay).start();            if(this.mActionView.getVisibility() == 0) {                ViewCompat.setAlpha(this.mActionView, 0.0F);                ViewCompat.animate(this.mActionView).alpha(1.0F).setDuration((long)duration).setStartDelay((long)delay).start();            }        }        void animateChildrenOut(int delay, int duration) {            ViewCompat.setAlpha(this.mMessageView, 1.0F);            ViewCompat.animate(this.mMessageView).alpha(0.0F).setDuration((long)duration).setStartDelay((long)delay).start();            if(this.mActionView.getVisibility() == 0) {                ViewCompat.setAlpha(this.mActionView, 1.0F);                ViewCompat.animate(this.mActionView).alpha(0.0F).setDuration((long)duration).setStartDelay((long)delay).start();            }        }        protected void onLayout(boolean changed, int l, int t, int r, int b) {            super.onLayout(changed, l, t, r, b);            if(changed && this.mOnLayoutChangeListener != null) {                this.mOnLayoutChangeListener.onLayoutChange(this, l, t, r, b);            }        }        void setOnLayoutChangeListener(Snackbar.SnackbarLayout.OnLayoutChangeListener onLayoutChangeListener) {            this.mOnLayoutChangeListener = onLayoutChangeListener;        }        private boolean updateViewsWithinLayout(int orientation, int messagePadTop, int messagePadBottom) {            boolean changed = false;            if(orientation != this.getOrientation()) {                this.setOrientation(orientation);                changed = true;            }            if(this.mMessageView.getPaddingTop() != messagePadTop || this.mMessageView.getPaddingBottom() != messagePadBottom) {                updateTopBottomPadding(this.mMessageView, messagePadTop, messagePadBottom);                changed = true;            }            return changed;        }        private static void updateTopBottomPadding(View view, int topPadding, int bottomPadding) {            if(ViewCompat.isPaddingRelative(view)) {                ViewCompat.setPaddingRelative(view, ViewCompat.getPaddingStart(view), topPadding, ViewCompat.getPaddingEnd(view), bottomPadding);            } else {                view.setPadding(view.getPaddingLeft(), topPadding, view.getPaddingRight(), bottomPadding);            }        }        interface OnLayoutChangeListener {            void onLayoutChange(View var1, int var2, int var3, int var4, int var5);        }    }    @Retention(RetentionPolicy.SOURCE)    public @interface Duration {    }}



0 0
原创粉丝点击