package com.sxjs.common.widget.bottomnavigation; import android.content.Context; import android.graphics.Color; import android.os.Build; import android.support.annotation.ColorRes; import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewPropertyAnimatorCompat; import android.support.v4.view.ViewPropertyAnimatorListener; import android.text.TextUtils; import android.view.Gravity; import android.view.View; import android.widget.FrameLayout; import android.widget.TextView; import java.lang.ref.WeakReference; /** * Class description : Holds and manages data for badges * (i.e data structure which holds all data to paint a badge and updates badges when changes are made) * * @author ashokvarma * @version 1.0 * @since 21 Apr 2016 */ public class BadgeItem { private int mBackgroundColorResource; private String mBackgroundColorCode; private int mBackgroundColor = Color.RED; private int mTextColorResource; private String mTextColorCode; private int mTextColor = Color.WHITE; private CharSequence mText; private int mBorderColorResource; private String mBorderColorCode; private int mBorderColor = Color.WHITE; private int mBorderWidth = 0; private int mGravity = Gravity.TOP ;//| Gravity.END; private boolean mHideOnSelect; private WeakReference<TextView> mTextViewRef; private boolean mIsHidden = false; private int mAnimationDuration = 200; /////////////////////////////////////////////////////////////////////////// // Public setter methods /////////////////////////////////////////////////////////////////////////// /** * @param colorResource resource for background color * @return this, to allow builder pattern */ public BadgeItem setBackgroundColorResource(@ColorRes int colorResource) { this.mBackgroundColorResource = colorResource; refreshDrawable(); return this; } /** * @param colorCode color code for background color * @return this, to allow builder pattern */ public BadgeItem setBackgroundColor(@Nullable String colorCode) { this.mBackgroundColorCode = colorCode; refreshDrawable(); return this; } /** * @param color background color * @return this, to allow builder pattern */ public BadgeItem setBackgroundColor(int color) { this.mBackgroundColor = color; refreshDrawable(); return this; } /** * @param colorResource resource for text color * @return this, to allow builder pattern */ public BadgeItem setTextColorResource(@ColorRes int colorResource) { this.mTextColorResource = colorResource; setTextColor(); return this; } /** * @param colorCode color code for text color * @return this, to allow builder pattern */ public BadgeItem setTextColor(@Nullable String colorCode) { this.mTextColorCode = colorCode; setTextColor(); return this; } /** * @param color text color * @return this, to allow builder pattern */ public BadgeItem setTextColor(int color) { this.mTextColor = color; setTextColor(); return this; } /** * @param text text to be set in badge (this shouldn't be empty text) * @return this, to allow builder pattern */ public BadgeItem setText(@Nullable CharSequence text) { this.mText = text; if (isWeakReferenceValid()) { TextView textView = mTextViewRef.get(); if (!TextUtils.isEmpty(text)) { textView.setText(text); } } return this; } /** * @param colorResource resource for border color * @return this, to allow builder pattern */ public BadgeItem setBorderColorResource(@ColorRes int colorResource) { this.mBorderColorResource = colorResource; refreshDrawable(); return this; } /** * @param colorCode color code for border color * @return this, to allow builder pattern */ public BadgeItem setBorderColor(@Nullable String colorCode) { this.mBorderColorCode = colorCode; refreshDrawable(); return this; } /** * @param color border color * @return this, to allow builder pattern */ public BadgeItem setBorderColor(int color) { this.mBorderColor = color; refreshDrawable(); return this; } /** * @param borderWidth border width in pixels * @return this, to allow builder pattern */ public BadgeItem setBorderWidth(int borderWidth) { this.mBorderWidth = borderWidth; refreshDrawable(); return this; } /** * @param gravity gravity of badge (TOP|LEFT ..etc) * @return this, to allow builder pattern */ public BadgeItem setGravity(int gravity) { this.mGravity = gravity; if (isWeakReferenceValid()) { TextView textView = mTextViewRef.get(); FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) textView.getLayoutParams(); layoutParams.gravity = gravity; textView.setLayoutParams(layoutParams); } return this; } /** * @param hideOnSelect if true hides badge on tab selection * @return this, to allow builder pattern */ public BadgeItem setHideOnSelect(boolean hideOnSelect) { this.mHideOnSelect = hideOnSelect; return this; } /** * @param animationDuration hide and show animation time * @return this, to allow builder pattern */ public BadgeItem setAnimationDuration(int animationDuration) { this.mAnimationDuration = animationDuration; return this; } /////////////////////////////////////////////////////////////////////////// // Library only access method /////////////////////////////////////////////////////////////////////////// /** * Internal method used to update view when ever changes are made * * @param mTextView badge textView * @return this, to allow builder pattern */ protected BadgeItem setTextView(TextView mTextView) { this.mTextViewRef = new WeakReference<>(mTextView); return this; } /** * @param context to fetch color * @return background color */ protected int getBackgroundColor(Context context) { if (this.mBackgroundColorResource != 0) { return ContextCompat.getColor(context, mBackgroundColorResource); } else if (!TextUtils.isEmpty(mBackgroundColorCode)) { return Color.parseColor(mBackgroundColorCode); } else { return mBackgroundColor; } } /** * @param context to fetch color * @return text color */ protected int getTextColor(Context context) { if (this.mTextColorResource != 0) { return ContextCompat.getColor(context, mTextColorResource); } else if (!TextUtils.isEmpty(mTextColorCode)) { return Color.parseColor(mTextColorCode); } else { return mTextColor; } } /** * @return text that needs to be set in badge */ protected CharSequence getText() { return mText; } /** * @param context to fetch color * @return border color */ protected int getBorderColor(Context context) { if (this.mBorderColorResource != 0) { return ContextCompat.getColor(context, mBorderColorResource); } else if (!TextUtils.isEmpty(mBorderColorCode)) { return Color.parseColor(mBorderColorCode); } else { return mBorderColor; } } /** * @return border width */ protected int getBorderWidth() { return mBorderWidth; } /** * @return gravity of badge */ protected int getGravity() { return mGravity; } /** * @return should hide on selection ? */ protected boolean isHideOnSelect() { return mHideOnSelect; } /** * @return reference to text-view */ protected WeakReference<TextView> getTextView() { return mTextViewRef; } /////////////////////////////////////////////////////////////////////////// // Internal Methods /////////////////////////////////////////////////////////////////////////// private void refreshDrawable() { if (isWeakReferenceValid()) { TextView textView = mTextViewRef.get(); textView.setBackgroundDrawable(BottomNavigationHelper.getBadgeDrawable(this, textView.getContext())); } } private void setTextColor() { if (isWeakReferenceValid()) { TextView textView = mTextViewRef.get(); textView.setTextColor(getTextColor(textView.getContext())); } } private boolean isWeakReferenceValid() { return mTextViewRef != null && mTextViewRef.get() != null; } /////////////////////////////////////////////////////////////////////////// // Internal call back methods /////////////////////////////////////////////////////////////////////////// /** * callback from bottom navigation tab when it is selected */ void select() { if (mHideOnSelect) { hide(true); } } /** * callback from bottom navigation tab when it is un-selected */ void unSelect() { if (mHideOnSelect) { show(true); } } /////////////////////////////////////////////////////////////////////////// // Public functionality methods /////////////////////////////////////////////////////////////////////////// /** * @return this, to allow builder pattern */ public BadgeItem toggle() { return toggle(true); } /** * @param animate whether to animate the change * @return this, to allow builder pattern */ public BadgeItem toggle(boolean animate) { if (mIsHidden) { return show(animate); } else { return hide(animate); } } /** * @return this, to allow builder pattern */ public BadgeItem show() { return show(true); } /** * @param animate whether to animate the change * @return this, to allow builder pattern */ public BadgeItem show(boolean animate) { mIsHidden = false; if (isWeakReferenceValid()) { TextView textView = mTextViewRef.get(); if (animate) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { textView.setScaleX(0); textView.setScaleY(0); } textView.setVisibility(View.VISIBLE); ViewPropertyAnimatorCompat animatorCompat = ViewCompat.animate(textView); animatorCompat.cancel(); animatorCompat.setDuration(mAnimationDuration); animatorCompat.scaleX(1).scaleY(1); animatorCompat.setListener(null); animatorCompat.start(); } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { textView.setScaleX(1); textView.setScaleY(1); } textView.setVisibility(View.VISIBLE); } } return this; } /** * @return this, to allow builder pattern */ public BadgeItem hide() { return hide(true); } /** * @param animate whether to animate the change * @return this, to allow builder pattern */ public BadgeItem hide(boolean animate) { mIsHidden = true; if (isWeakReferenceValid()) { TextView textView = mTextViewRef.get(); if (animate) { ViewPropertyAnimatorCompat animatorCompat = ViewCompat.animate(textView); animatorCompat.cancel(); animatorCompat.setDuration(mAnimationDuration); animatorCompat.scaleX(0).scaleY(0); animatorCompat.setListener(new ViewPropertyAnimatorListener() { @Override public void onAnimationStart(View view) { // Empty body } @Override public void onAnimationEnd(View view) { view.setVisibility(View.GONE); } @Override public void onAnimationCancel(View view) { view.setVisibility(View.GONE); } }); animatorCompat.start(); } else { textView.setVisibility(View.GONE); } } return this; } /** * @return if the badge is hidden */ public boolean isHidden() { return mIsHidden; } }