Snackbars從頂部滑出的實現
阿新 • • 發佈:2019-02-07
需要多個類的幫助,有需要的直接下載程式碼
記住需要先匯入依賴包:compile ‘com.android.support:design:23.0.0’
主要程式碼的幫助類
- 幫助類1
import java.lang.ref.WeakReference;
/**
* Snackbar的管理者
*/
class SnackbarManager {
private static final int MSG_TIMEOUT = 0;
private static final int SHORT_DURATION_MS = 1500;
private static final int LONG_DURATION_MS = 2750;
private static SnackbarManager sSnackbarManager;
static SnackbarManager getInstance() {
if (sSnackbarManager == null) {
sSnackbarManager = new SnackbarManager();
}
return sSnackbarManager;
}
private final Object mLock;
private final Handler mHandler;
private SnackbarRecord mCurrentSnackbar;
private SnackbarRecord mNextSnackbar;
private SnackbarManager() {
mLock = new Object();
mHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
switch (message.what) {
case MSG_TIMEOUT:
handleTimeout((SnackbarRecord) message.obj);
return true;
}
return false;
}
});
}
interface Callback {
void show();
void dismiss(int event);
}
public void show(int duration, Callback callback) {
synchronized (mLock) {
if (isCurrentSnackbarLocked(callback)) {
// 味著回撥已經在佇列中
mCurrentSnackbar.duration = duration;
// If this is the Snackbar currently being shown, call re-schedule it's
// timeout
mHandler.removeCallbacksAndMessages(mCurrentSnackbar);
scheduleTimeoutLocked(mCurrentSnackbar);
return;
} else if (isNextSnackbarLocked(callback)) {
// We'll just update the duration
mNextSnackbar.duration = duration;
} else {
// Else, we need to create a new record and queue it
mNextSnackbar = new SnackbarRecord(duration, callback);
}
if (mCurrentSnackbar != null && cancelSnackbarLocked(mCurrentSnackbar,
Snackbar.Callback.DISMISS_EVENT_CONSECUTIVE)) {
// If we currently have a Snackbar, try and cancel it and wait in line
return;
} else {
// Clear out the current snackbar
mCurrentSnackbar = null;
// Otherwise, just show it now
showNextSnackbarLocked();
}
}
}
public void dismiss(Callback callback, int event) {
synchronized (mLock) {
if (isCurrentSnackbarLocked(callback)) {
cancelSnackbarLocked(mCurrentSnackbar, event);
} else if (isNextSnackbarLocked(callback)) {
cancelSnackbarLocked(mNextSnackbar, event);
}
}
}
/**
* Snackbar不再顯示,退出動畫完成。
*/
public void onDismissed(Callback callback) {
synchronized (mLock) {
if (isCurrentSnackbarLocked(callback)) {
// If the callback is from a Snackbar currently show, remove it and show a new one
mCurrentSnackbar = null;
if (mNextSnackbar != null) {
showNextSnackbarLocked();
}
}
}
}
/**
* Snackbar被顯示。這是在任何入口動畫完成。
*/
public void onShown(Callback callback) {
synchronized (mLock) {
if (isCurrentSnackbarLocked(callback)) {
scheduleTimeoutLocked(mCurrentSnackbar);
}
}
}
public void cancelTimeout(Callback callback) {
synchronized (mLock) {
if (isCurrentSnackbarLocked(callback)) {
mHandler.removeCallbacksAndMessages(mCurrentSnackbar);
}
}
}
public void restoreTimeout(Callback callback) {
synchronized (mLock) {
if (isCurrentSnackbarLocked(callback)) {
scheduleTimeoutLocked(mCurrentSnackbar);
}
}
}
public boolean isCurrent(Callback callback) {
synchronized (mLock) {
return isCurrentSnackbarLocked(callback);
}
}
public boolean isCurrentOrNext(Callback callback) {
synchronized (mLock) {
return isCurrentSnackbarLocked(callback) || isNextSnackbarLocked(callback);
}
}
private static class SnackbarRecord {
private final WeakReference<Callback> callback;
private int duration;
SnackbarRecord(int duration, Callback callback) {
this.callback = new WeakReference<>(callback);
this.duration = duration;
}
boolean isSnackbar(Callback callback) {
return callback != null && this.callback.get() == callback;
}
}
private void showNextSnackbarLocked() {
if (mNextSnackbar != null) {
mCurrentSnackbar = mNextSnackbar;
mNextSnackbar = null;
final Callback callback = mCurrentSnackbar.callback.get();
if (callback != null) {
callback.show();
} else {
// The callback doesn't exist any more, clear out the Snackbar
mCurrentSnackbar = null;
}
}
}
private boolean cancelSnackbarLocked(SnackbarRecord record, int event) {
final Callback callback = record.callback.get();
if (callback != null) {
// Make sure we remove any timeouts for the SnackbarRecord
mHandler.removeCallbacksAndMessages(record);
callback.dismiss(event);
return true;
}
return false;
}
private boolean isCurrentSnackbarLocked(Callback callback) {
return mCurrentSnackbar != null && mCurrentSnackbar.isSnackbar(callback);
}
private boolean isNextSnackbarLocked(Callback callback) {
return mNextSnackbar != null && mNextSnackbar.isSnackbar(callback);
}
private void scheduleTimeoutLocked(SnackbarRecord r) {
if (r.duration == Snackbar.LENGTH_INDEFINITE) {
// 如果我們不確定,我們不希望設定一個超時
return;
}
int durationMs = LONG_DURATION_MS;
if (r.duration > 0) {
durationMs = r.duration;
} else if (r.duration == Snackbar.LENGTH_SHORT) {
durationMs = SHORT_DURATION_MS;
}
mHandler.removeCallbacksAndMessages(r);
mHandler.sendMessageDelayed(Message.obtain(mHandler, MSG_TIMEOUT, r), durationMs);
}
private void handleTimeout(SnackbarRecord record) {
synchronized (mLock) {
if (mCurrentSnackbar == record || mNextSnackbar == record) {
cancelSnackbarLocked(record, Snackbar.Callback.DISMISS_EVENT_TIMEOUT);
}
}
}
}
- 幫助類2
import android.app.Activity;
import android.app.ActivityGroup;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
/**
* 獲得螢幕相關的輔助類
*/
public class ScreenUtil {
private ScreenUtil() {
/* 不能被例項化 */
throw new UnsupportedOperationException("cannot be instantiated");
}
private static int mStatusHeight = -1;
/**
* 獲得狀態列的高度
*/
public static int getStatusHeight(Context context) {
if (mStatusHeight != -1) {
return mStatusHeight;
}
try {
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
mStatusHeight = context.getResources().getDimensionPixelSize(resourceId);
}
} catch (Exception e) {
e.printStackTrace();
}
return mStatusHeight;
}
/**
* 獲取當前螢幕截圖,不包含狀態列
*/
public static Bitmap snapShotWithoutStatusBar(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bmp = view.getDrawingCache();
if (bmp == null) {
return null;
}
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
Bitmap bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, bmp.getWidth(), bmp.getHeight() - statusBarHeight);
view.destroyDrawingCache();
view.setDrawingCacheEnabled(false);
return bp;
}
/**
* 獲取actionbar的畫素高度,預設使用android官方相容包做actionbar相容
*/
public static int getActionBarHeight(Context context) {
int actionBarHeight = 0;
if (context instanceof AppCompatActivity && ((AppCompatActivity) context).getSupportActionBar() != null) {
Log.d("isAppCompatActivity", "==AppCompatActivity");
actionBarHeight = ((AppCompatActivity) context).getSupportActionBar().getHeight();
} else if (context instanceof Activity && ((Activity) context).getActionBar() != null) {
Log.d("isActivity", "==Activity");
actionBarHeight = ((Activity) context).getActionBar().getHeight();
} else if (context instanceof ActivityGroup) {
Log.d("ActivityGroup", "==ActivityGroup");
if (((ActivityGroup) context).getCurrentActivity() instanceof AppCompatActivity && ((AppCompatActivity) ((ActivityGroup) context).getCurrentActivity()).getSupportActionBar() != null) {
actionBarHeight = ((AppCompatActivity) ((ActivityGroup) context).getCurrentActivity()).getSupportActionBar().getHeight();
} else if (((ActivityGroup) context).getCurrentActivity() instanceof Activity && ((Activity) ((ActivityGroup) context).getCurrentActivity()).getActionBar() != null) {
actionBarHeight = ((Activity) ((ActivityGroup) context).getCurrentActivity()).getActionBar().getHeight();
}
}
if (actionBarHeight != 0)
return actionBarHeight;
final TypedValue tv = new TypedValue();
if (context.getTheme().resolveAttribute(android.support.v7.appcompat.R.attr.actionBarSize, tv, true)) {
if (context.getTheme().resolveAttribute(android.support.v7.appcompat.R.attr.actionBarSize, tv, true))
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
} else {
if (context.getTheme().resolveAttribute(android.support.v7.appcompat.R.attr.actionBarSize, tv, true))
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
}
Log.d("actionBarHeight", "====" + actionBarHeight);
return actionBarHeight;
}
/**
* 設定view margin
*/
public static void setMargins(View v, int l, int t, int r, int b) {
if (v.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
p.setMargins(l, t, r, b);
v.requestLayout();
}
}
}
- 幫助類3
package snackbarutil;
import com.example.administrator.snackbars.R;
/**
* 彈出Snackbar時,圖示已經背景色的改變
*/
public enum Prompt {//列舉定義的常量
/**
* 紅色,錯誤
*/
ERROR(R.mipmap.icon_error, R.color.error),
/**
* 紅色,警告
*/
WARNING(R.mipmap.icon_warning, R.color.warning),
/**
* 綠色,成功
*/
SUCCESS(R.mipmap.icon_successful, R.color.success);
private int resIcon;
private int backgroundColor;
Prompt(int resIcon, int backgroundColor) {
this.resIcon = resIcon;
this.backgroundColor = backgroundColor;
}
public int getResIcon() {
return resIcon;
}
public void setResIcon(int resIcon) {
this.resIcon = resIcon;
}
public int getBackgroundColor() {
return backgroundColor;
}
public void setBackgroundColor(int backgroundColor) {
this.backgroundColor = backgroundColor;
}
}
- 幫助類4
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.support.v4.view.animation.LinearOutSlowInInterpolator;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
/**
* 動畫工具類
*/
public class AnimationUtils {
static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
static final Interpolator FAST_OUT_SLOW_IN_INTERPOLATOR = new FastOutSlowInInterpolator();
static final Interpolator FAST_OUT_LINEAR_IN_INTERPOLATOR = new FastOutLinearInInterpolator();
static final Interpolator LINEAR_OUT_SLOW_IN_INTERPOLATOR = new LinearOutSlowInInterpolator();
static final Interpolator DECELERATE_INTERPOLATOR = new DecelerateInterpolator();
static float lerp(float startValue, float endValue, float fraction) {
return startValue + (fraction * (endValue - startValue));
}
static int lerp(int startValue, int endValue, float fraction) {
return startValue + Math.round(fraction * (endValue - startValue));
}
/**
* 動畫的監聽
*/
static class AnimationListenerAdapter implements Animation.AnimationListener {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
}
}
- 幫助類5
自定義的Snackbar
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.ColorInt;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.SwipeDismissBehavior;
import android.support.v4.view.ViewCompat;
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.accessibility.AccessibilityManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.administrator.snackbars.R;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* TSnackbar提供輕量級的反饋對一個操作。他們顯示一個簡短的資訊
* 包含一組動作是通過{ setAction(CharSequence進行View.OnClickListener)}。
* 通知Snackbar已被證明或者被辭退的,您可以提供一個{ setCallback(回撥)} }
*/
public final class TSnackbar {
/**
* 回撥類的例項。setCallback(Callback)
*/
public static abstract class Callback {
/**
* 表明TSnackbar通過猛擊而消失。
*/
public static final int DISMISS_EVENT_SWIPE = 0;
/**
* 表明TSnackbar通過操作點選而消失。
*/
public static final int DISMISS_EVENT_ACTION = 1;
/**
* 表明TSnackbar通過超時而消失。
*/
public static final int DISMISS_EVENT_TIMEOUT = 2;
/**
* 表明TSnackbar通過呼叫{ dismiss()}而消失
*/
public static final int DISMISS_EVENT_MANUAL = 3;
/**
* 表明TSnackbar被另一個Tsnackbar出現而消失
*/
public static final int DISMISS_EVENT_CONSECUTIVE = 4;
@IntDef({DISMISS_EVENT_SWIPE, DISMISS_EVENT_ACTION, DISMISS_EVENT_TIMEOUT,
DISMISS_EVENT_MANUAL, DISMISS_EVENT_CONSECUTIVE})
@Retention(RetentionPolicy.SOURCE)
public @interface DismissEvent {
}
/**
* snackbar的事件導致消失。之一:
* { DISMISS_EVENT_SWIPE },{ DISMISS_EVENT_ACTION },
* { DISMISS_EVENT_TIMEOUT },{ DISMISS_EVENT_MANUAL }
* { DISMISS_EVENT_CONSECUTIVE }。
*/
public void onDismissed(TSnackbar TSnackbar, @DismissEvent int event) {
}
/**
* TSnackbar是可見的.
*/
public void onShown(TSnackbar TSnackbar) {
}
}
@IntDef({APPEAR_FROM_TOP_TO_DOWN, APPEAR_FROM_BOTTOM_TO_TOP})
@Retention(RetentionPolicy.SOURCE)
public @interface OverSnackAppearDirection {
}
/**
* 顯示TSnackbar從上到下
*/
public static final int APPEAR_FROM_TOP_TO_DOWN = 0;
/**
* 顯示TSnackbar從下到上
*/
public static final int APPEAR_FROM_BOTTOM_TO_TOP = 1;
@IntDef({LENGTH_INDEFINITE, LENGTH_SHORT, LENGTH_LONG})
@Retention(RetentionPolicy.SOURCE)
public @interface Duration {
}
/**
* 顯示TSnackbar消失。這意味著TSnackbar將顯示的時間
* 這是{ show() },直到它被解職,或另一個TSnackbar顯示。
*
* @see #setDuration
*/
public static final int LENGTH_INDEFINITE = -2; //無限長
/**
* 顯示TSnackbar很短的一段時間。
*
* @see #setDuration
*/
public static final int LENGTH_SHORT = -1; //短時間
/**
* 顯示TSnackbar很長一段時間。
*
* @see #setDuration
*/
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;
private static final int MSG_SHOW = 0;
private static final int MSG_DISMISS = 1;
private
@OverSnackAppearDirection
int appearDirection;
static {
sHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
switch (message.what) {
case MSG_SHOW:
((TSnackbar) message.obj).showView();
return true;
case MSG_DISMISS:
((TSnackbar) message.obj).hideView(message.arg1);
return true;
}
return false;
}
});
}
private final ViewGroup mParent;
private final Context mContext;
private final SnackbarLayout mView;
private int mDuration;
private Callback mCallback;
private final AccessibilityManager mAccessibilityManager;
private TSnackbar(ViewGroup parent) {
appearDirection = APPEAR_FROM_TOP_TO_DOWN;
mParent = parent;
mContext = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(mContext);
//顯示Snackbar的佈局
mView = (SnackbarLayout) inflater.inflate(R.layout.view_tsnackbar_layout, mParent, false);
mAccessibilityManager = (AccessibilityManager)
mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
}
private TSnackbar(ViewGroup parent, @OverSnackAppearDirection int appearDirection) {
this(parent);
this.appearDirection = appearDirection;
if (appearDirection == APPEAR_FROM_TOP_TO_DOWN) {
setMinHeight(0, 0);
}
}
/**
* 設定TSnackbar最小的高度
*/
public TSnackbar setMinHeight(int stateBarHeight, int actionBarHeight) {
if (appearDirection == APPEAR_FROM_TOP_TO_DOWN) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (stateBarHeight > 0 || actionBarHeight > 0) {
mView.setPadding(0, stateBarHeight, 0, 0);
mView.setMinimumHeight(stateBarHeight + actionBarHeight);
} else {
mView.setPadding(0, ScreenUtil.getStatusHeight(mContext), 0, 0);
mView.setMinimumHeight(ScreenUtil.getActionBarHeight(mContext) + ScreenUtil.getStatusHeight(mContext));
}
} else {
if (stateBarHeight > 0 || actionBarHeight > 0) {
mView.setMinimumHeight(actionBarHeight);
ScreenUtil.setMargins(mView, 0, stateBarHeight, 0, 0);
} else {
mView.setMinimumHeight(ScreenUtil.getActionBarHeight(mContext));
ScreenUtil.setMargins(mView, 0, ScreenUtil.getStatusHeight(mContext), 0, 0);
}
}
}
return this;
}
/**
* TSnackbar顯示一條訊息
* 這是定義為一個{ @link CoordinatorLayout }或視窗裝飾的內容來看,以先到期者作準。
* 有一個{ CoordinatorLayout }在檢視層次結構允許TSnackbar啟用某些特性,
* 如swipe-to-dismiss和自動移動的小部件{ @link FloatingActionButton }。
*
* @param檢視的父控制元件。
* @param文字顯示的文字。可以格式化文字。
* @param持續時間多久來顯示資訊。{ LENGTH_SHORT }或{ LENGTH_LONG }
*/
@NonNull
public static TSnackbar make(@NonNull View view, @NonNull CharSequence text, @Duration int duration) {
TSnackbar tSnackbar = new TSnackbar(findSuitableParent(view), APPEAR_FROM_TOP_TO_DOWN);
tSnackbar.setText(text);
tSnackbar.setDuration(duration);
return tSnackbar;
}
@NonNull
public static TSnackbar make(@NonNull View view, @NonNull CharSequence text, @Duration int duration, @OverSnackAppearDirection int appearDirection) {
TSnackbar tSnackbar = new TSnackbar(findSuitableParent(view), appearDirection); //出現的方向
tSnackbar.setText(text);
tSnackbar.setDuration(duration);
return tSnackbar;
}
@NonNull
public static TSnackbar make(@NonNull View view, @StringRes int resId, @Duration int duration) {
return make(view, view.getResources().getText(resId), duration);
}
private static ViewGroup findSuitableParent(View view) {
ViewGroup fallback = null;
do {
if (view instanceof CoordinatorLayout) {
return (ViewGroup) view;
} else if (view instanceof FrameLayout) {
if (view.getId() == android.R.id.content) {
return (ViewGroup) view;
} else {
fallback = (ViewGroup) view;
}
}
if (view != null) {
final ViewParent parent = view.getParent();
view = parent instanceof View ? (View) parent : null;
}
} while (view != null);
return fallback;
}
/**
* 給TSnackbar上新增圖示
*
* @param resource_id
* @return
*/
public TSnackbar addIcon(int resource_id) {
final TextView tv = mView.getMessageView();
tv.setCompoundDrawablesWithIntrinsicBounds(mContext.getResources().getDrawable(resource_id), null, null, null);
return this;
}
/**
* @param resource_id image id
* @param width image width
* @param height image height
* @return
*/
public TSnackbar addIcon(int resource_id, int width, int height) {
final TextView tv = mView.getMessageView();
if (width > 0 || height > 0) {
tv.setCompoundDrawablesWithIntrinsicBounds(new BitmapDrawable(Bitmap.createScaledBitmap(((BitmapDrawable) (mContext.getResources().getDrawable(resource_id))).getBitmap(), width, height, true)), null, null, null);
} else {
addIcon(resource_id);
}
return this;
}
/**
* 顯示載入progressBar
*
* @param resource_id image id
* @param left show textview left
* @param right show textview right
* @return TSnackbar
*/
public TSnackbar addIconProgressLoading(int resource_id, boolean left, boolean right) {
Drawable drawable = mContext.getResources().getDrawable(R.drawable.rotate);//載入進度條
if (resource_id > 0) {
drawable = mContext.getResources().getDrawable(resource_id);
}
addIconProgressLoading(drawable, left, right);
return this;
}
/**
* 新增載入的圖示
* @param drawable
* @param left true 表示在左邊
* @param right
* @return
*/
public TSnackbar addIconProgressLoading(Drawable drawable, boolean left, boolean right) {
final ObjectAnimator animator = ObjectAnimator.ofInt(drawable, "level", 0, 10000);
animator.setDuration(1000);
animator.setInterpolator(new LinearInterpolator());
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setRepeatMode(ValueAnimator.INFINITE);
mView.setBackgroundColor(mContext.getResources().getColor(Prompt.SUCCESS.getBackgroundColor()));
if (left) {
mView.getMessageView().setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
}
if (right) {
mView.getMessageView().setCompoundDrawablesWithIntrinsicBounds(null, null, drawable, null);
}
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
if (mCallback != null) {
mCallback.onShown(TSnackbar.this);
}
SnackbarManager.getInstance().onShown(mManagerCallback);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animator.start();
return this;
}
/**
* 預設風格{錯誤、警告成功} {ERROR , WARNING , SUCCESS}
*/
public TSnackbar setPromptThemBackground(Prompt prompt) {
if (prompt == Prompt.SUCCESS) {
setBackgroundColor(mContext.getResources().getColor(Prompt.SUCCESS.getBackgroundColor()));
addIcon(Prompt.SUCCESS.getResIcon(), 0, 0);
} else if (prompt == Prompt.ERROR) {
setBackgroundColor(mContext.getResources().getColor(Prompt.ERROR.getBackgroundColor()));
addIcon(Prompt.ERROR.getResIcon(), 0, 0);
} else if (prompt == Prompt.WARNING) {
setBackgroundColor(mContext.getResources().getColor(Prompt.WARNING.getBackgroundColor()));
addIcon(Prompt.WARNING.getResIcon(), 0, 0);
}
return this;
}
/**
* 設定TSnackbar的背景色
*/
public TSnackbar setBackgroundColor(int colorId) {
mView.setBackgroundColor(colorId);
return this;
}
/**
* 設定TSnackbar上的動作
*/
@NonNull
public TSnackbar setAction(@StringRes int resId, View.OnClickListener listener) {
return setAction(mContext.getText(resId), listener);
}
@NonNull
public TSnackbar setAction(CharSequence text, final View.OnClickListener listener) {
final TextView tv = mView.getActionView();
if (TextUtils.isEmpty(text) || listener == null) {
tv.setVisibility(View.GONE);
tv.setOnClickListener(null);
} else {
tv.setVisibility(View.VISIBLE);
tv.setText(text);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onClick(view);
dispatchDismiss(Callback.DISMISS_EVENT_ACTION);
}
});
}
return this;
}
/**
* 設定這個動作上文字的顏色
*/
@NonNull
public TSnackbar setActionTextColor(ColorStateList colors) {
final TextView tv = mView.getActionView();
tv.setTextColor(colors);
return this;
}
@NonNull
public TSnackbar setActionTextColor(@ColorInt int color) {
final TextView tv = mView.getActionView();
tv.setTextColor(color);
return this;
}
/**
* 更改TSnackbar的文字
*/
@NonNull
public TSnackbar setText(@NonNull CharSequence message) {
final TextView tv = mView.getMessageView();
tv.setText(message);
return this;
}
@NonNull
public TSnackbar setText(@StringRes int resId) {
return setText(mContext.getText(resId));
}
/**
* 設定多長時間顯示的檢視。
*/
@NonNull
public TSnackbar setDuration(@Duration int duration) {
mDuration = duration;
return this;
}
/**
* 得到時間
*/
@Duration
public int getDuration() {
return mDuration;
}
/**
* 得到view
*/
@NonNull
public View getView() {
return mView;
}
/**
* 顯示TSnackbar
*/
public void show() {
SnackbarManager.getInstance().show(mDuration, mManagerCallback);
}
/**
* TSnackbar消失
*/
public void dismiss() {
dispatchDismiss(Callback.DISMISS_EVENT_MANUAL);
}
private void dispatchDismiss(@Callback.DismissEvent int event) {
SnackbarManager.getInstance().dismiss(mManagerCallback, event);
}
/**
* 設定回撥時TSnackbar的可見性變化。
*/
@NonNull
public TSnackbar setCallback(Callback callback) {
mCallback = callback;
return this;
}
/**
* 返回TSnackbar 是否目前顯示。
*/
public boolean isShown() {
return SnackbarManager.getInstance().isCurrent(mManagerCallback);
}
/**
* 返回TSnackbar 是否 目前顯示,還是排隊顯示
*/
public boolean isShownOrQueued() {
return SnackbarManager.getInstance().isCurrentOrNext(mManagerCallback);
}
private final SnackbarManager.Callback mManagerCallback = new SnackbarManager.Callback() {
@Override
public void show() {
sHandler.sendMessage(sHandler.obtainMessage(MSG_SHOW, TSnackbar.this));
}
@Override
public void dismiss(int event) {
sHandler.sendMessage(sHandler.obtainMessage(MSG_DISMISS, event, 0, TSnackbar.this));
}
};
final void showView() {
if (mView.getParent() == null) {
final ViewGroup.LayoutParams lp = mView.getLayoutParams();
if (lp instanceof CoordinatorLayout.LayoutParams) {
// If our LayoutParams are from a CoordinatorLayout, we'll setup our Behavior
final Behavior behavior = new Behavior();
behavior.setStartAlphaSwipeDistance(0.1f);
behavior.setEndAlphaSwipeDistance(0.6f);
behavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_START_TO_END);
behavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
@Override
public void onDismiss(View view) {
view.setVisibility(View.GONE);
dispatchDismiss(Callback.DISMISS_EVENT_SWIPE);
}
@Override
public void onDragStateChanged(int state) {
switch (state) {
case SwipeDismissBehavior.STATE_DRAGGING:
case SwipeDismissBehavior.STATE_SETTLING:
SnackbarManager.getInstance().cancelTimeout(mManagerCallback);