diff options
author | Aurelien Hubert <aurel.hubert@gmail.com> | 2016-03-25 19:28:42 +0100 |
---|---|---|
committer | Aurelien Hubert <aurel.hubert@gmail.com> | 2016-03-25 19:28:42 +0100 |
commit | 3f0423373f85e34643d0eb1aa76d926ee408a22e (patch) | |
tree | 045d88cf2cf84f6acae11ee8823ac7ed08ff768b /ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation | |
parent | ee1a23bf7316a3d966e9552159ddce0f9284cf8f (diff) | |
download | android_external_ahbottomnavigation-3f0423373f85e34643d0eb1aa76d926ee408a22e.tar.gz android_external_ahbottomnavigation-3f0423373f85e34643d0eb1aa76d926ee408a22e.tar.bz2 android_external_ahbottomnavigation-3f0423373f85e34643d0eb1aa76d926ee408a22e.zip |
Bug fixes
Add notifications
Min SDK version is now 14
Diffstat (limited to 'ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation')
-rw-r--r-- | ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation/AHBottomNavigation.java | 214 | ||||
-rw-r--r-- | ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation/AHHelper.java | 50 |
2 files changed, 224 insertions, 40 deletions
diff --git a/ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation/AHBottomNavigation.java b/ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation/AHBottomNavigation.java index c65d307..a3fff0d 100644 --- a/ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation/AHBottomNavigation.java +++ b/ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation/AHBottomNavigation.java @@ -3,8 +3,11 @@ package com.aurelhubert.ahbottomnavigation; import android.animation.Animator; import android.content.Context; import android.graphics.Color; +import android.graphics.Typeface; +import android.graphics.drawable.Drawable; import android.os.Build; import android.support.annotation.ColorInt; +import android.support.annotation.ColorRes; import android.support.design.widget.CoordinatorLayout; import android.support.v4.content.ContextCompat; import android.util.AttributeSet; @@ -44,6 +47,7 @@ public class AHBottomNavigation extends FrameLayout { private ArrayList<View> views = new ArrayList<>(); private View backgroundColorView; private boolean colored = false; + private int[] notifications = {0, 0, 0, 0, 0}; private int defaultBackgroundColor = Color.WHITE; private int accentColor = Color.WHITE; @@ -56,6 +60,12 @@ public class AHBottomNavigation extends FrameLayout { private boolean forceTint = false; private boolean forceTitlesDisplay = false; + // Notifications + private @ColorInt int notificationTextColor; + private @ColorInt int notificationBackgroundColor; + private Drawable notificationBackgroundDrawable; + private Typeface notificationTypeface; + /** * Constructor @@ -65,19 +75,19 @@ public class AHBottomNavigation extends FrameLayout { public AHBottomNavigation(Context context) { super(context); this.context = context; - initColors(); + init(); } public AHBottomNavigation(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; - initColors(); + init(); } public AHBottomNavigation(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; - initColors(); + init(); } @@ -99,11 +109,12 @@ public class AHBottomNavigation extends FrameLayout { ///////////// /** - * Init the default colors + * Init */ - private void initColors() { + private void init() { accentColor = ContextCompat.getColor(context, R.color.colorAccent); inactiveColor = ContextCompat.getColor(context, R.color.colorInactive); + notificationTextColor = ContextCompat.getColor(context, android.R.color.white); } /** @@ -216,9 +227,12 @@ public class AHBottomNavigation extends FrameLayout { if (i == currentItem) { int activePaddingTop = (int) context.getResources() - .getDimension(R.dimen.bottom_navigation_padding_top_active); - view.setPadding(view.getPaddingLeft(), activePaddingTop, view.getPaddingRight(), - view.getPaddingBottom()); + .getDimension(R.dimen.bottom_navigation_margin_top_active); + if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) { + ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) icon.getLayoutParams(); + p.setMargins(p.leftMargin, activePaddingTop, p.rightMargin, p.bottomMargin); + view.requestLayout(); + } } if (colored) { @@ -253,6 +267,8 @@ public class AHBottomNavigation extends FrameLayout { linearLayout.addView(view, params); views.add(view); } + + updateNotifications(true); } /** @@ -298,12 +314,13 @@ public class AHBottomNavigation extends FrameLayout { title.setText(item.getTitle(context)); if (i == currentItem) { - int activePaddingTop = (int) context.getResources() - .getDimension(R.dimen.bottom_navigation_small_padding_top_active); - int activePaddingBottom = (int) context.getResources() - .getDimension(R.dimen.bottom_navigation_padding_bottom); - view.setPadding(view.getPaddingLeft(), activePaddingTop, view.getPaddingRight(), - activePaddingBottom); + int activeMarginTop = (int) context.getResources() + .getDimension(R.dimen.bottom_navigation_small_margin_top_active); + if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) { + ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) icon.getLayoutParams(); + p.setMargins(p.leftMargin, activeMarginTop, p.rightMargin, p.bottomMargin); + view.requestLayout(); + } } if (colored) { @@ -333,11 +350,13 @@ public class AHBottomNavigation extends FrameLayout { } }); - LayoutParams params = new LayoutParams( - i == currentItem ? (int) selectedItemWidth : (int) itemWidth, (int) height); + LayoutParams params = new LayoutParams( i == currentItem ? (int) selectedItemWidth : + (int) itemWidth, (int) height); linearLayout.addView(view, params); views.add(view); } + + updateNotifications(true); } @@ -353,8 +372,10 @@ public class AHBottomNavigation extends FrameLayout { return; } - int activePaddingTop = (int) context.getResources().getDimension(R.dimen.bottom_navigation_padding_top_active); - int inactivePaddingTop = (int) context.getResources().getDimension(R.dimen.bottom_navigation_padding_top_inactive); + int activeMarginTop = (int) context.getResources().getDimension(R.dimen.bottom_navigation_margin_top_active); + int inactiveMarginTop = (int) context.getResources().getDimension(R.dimen.bottom_navigation_margin_top_inactive); + int notificationActiveMarginLeft = (int) context.getResources().getDimension(R.dimen.bottom_navigation_notification_margin_left_active); + int notificationInactiveMarginLeft = (int) context.getResources().getDimension(R.dimen.bottom_navigation_notification_margin_left); float activeSize = context.getResources().getDimension(R.dimen.bottom_navigation_text_size_active); float inactiveSize = context.getResources().getDimension(R.dimen.bottom_navigation_text_size_inactive); if (forceTitlesDisplay && items.size() > MIN_ITEMS) { @@ -371,11 +392,12 @@ public class AHBottomNavigation extends FrameLayout { if (i == itemIndex) { - final View container = views.get(itemIndex).findViewById(R.id.bottom_navigation_container); final TextView title = (TextView) views.get(itemIndex).findViewById(R.id.bottom_navigation_item_title); final ImageView icon = (ImageView) views.get(itemIndex).findViewById(R.id.bottom_navigation_item_icon); + final TextView notification = (TextView) views.get(itemIndex).findViewById(R.id.bottom_navigation_notification); - AHHelper.updateTopPadding(container, inactivePaddingTop, activePaddingTop); + AHHelper.updateTopMargin(icon, inactiveMarginTop, activeMarginTop); + AHHelper.updateLeftMargin(notification, notificationInactiveMarginLeft, notificationActiveMarginLeft); AHHelper.updateTextColor(title, itemInactiveColor, itemActiveColor); AHHelper.updateTextSize(title, inactiveSize, activeSize); AHHelper.updateDrawableColor(context, items.get(itemIndex).getDrawable(context), icon, @@ -416,11 +438,12 @@ public class AHBottomNavigation extends FrameLayout { } else if (i == currentItem) { - final View container = views.get(currentItem).findViewById(R.id.bottom_navigation_container); final TextView title = (TextView) views.get(currentItem).findViewById(R.id.bottom_navigation_item_title); final ImageView icon = (ImageView) views.get(currentItem).findViewById(R.id.bottom_navigation_item_icon); + final TextView notification = (TextView) views.get(currentItem).findViewById(R.id.bottom_navigation_notification); - AHHelper.updateTopPadding(container, activePaddingTop, inactivePaddingTop); + AHHelper.updateTopMargin(icon, activeMarginTop, inactiveMarginTop); + AHHelper.updateLeftMargin(notification, notificationActiveMarginLeft, notificationInactiveMarginLeft); AHHelper.updateTextColor(title, itemActiveColor, itemInactiveColor); AHHelper.updateTextSize(title, activeSize, inactiveSize); AHHelper.updateDrawableColor(context, items.get(currentItem).getDrawable(context), icon, @@ -451,8 +474,10 @@ public class AHBottomNavigation extends FrameLayout { return; } - int activePaddingTop = (int) context.getResources().getDimension(R.dimen.bottom_navigation_small_padding_top_active); - int inactivePadding = (int) context.getResources().getDimension(R.dimen.bottom_navigation_small_padding_top); + int activeMarginTop = (int) context.getResources().getDimension(R.dimen.bottom_navigation_small_margin_top_active); + int inactiveMargin = (int) context.getResources().getDimension(R.dimen.bottom_navigation_small_margin_top); + int notificationActiveMarginLeft = (int) context.getResources().getDimension(R.dimen.bottom_navigation_notification_margin_left_active); + int notificationInactiveMarginLeft = (int) context.getResources().getDimension(R.dimen.bottom_navigation_notification_margin_left); int itemActiveColor = colored ? ContextCompat.getColor(context, R.color.colorActiveSmall) : accentColor; int itemInactiveColor = colored ? ContextCompat.getColor(context, R.color.colorInactiveSmall) : @@ -462,11 +487,14 @@ public class AHBottomNavigation extends FrameLayout { if (i == itemIndex) { - final View container = views.get(itemIndex).findViewById(R.id.bottom_navigation_small_container); + + final FrameLayout container = (FrameLayout) views.get(itemIndex).findViewById(R.id.bottom_navigation_small_container); final TextView title = (TextView) views.get(itemIndex).findViewById(R.id.bottom_navigation_small_item_title); final ImageView icon = (ImageView) views.get(itemIndex).findViewById(R.id.bottom_navigation_small_item_icon); + final TextView notification = (TextView) views.get(itemIndex).findViewById(R.id.bottom_navigation_notification); - AHHelper.updateTopPadding(container, inactivePadding, activePaddingTop); + AHHelper.updateTopMargin(icon, inactiveMargin, activeMarginTop); + AHHelper.updateLeftMargin(notification, notificationInactiveMarginLeft, notificationActiveMarginLeft); AHHelper.updateTextColor(title, itemInactiveColor, itemActiveColor); AHHelper.updateAlpha(title, 0, 1); AHHelper.updateWidth(container, notSelectedItemWidth, selectedItemWidth); @@ -510,13 +538,16 @@ public class AHBottomNavigation extends FrameLayout { final View container = views.get(currentItem).findViewById(R.id.bottom_navigation_small_container); final TextView title = (TextView) views.get(currentItem).findViewById(R.id.bottom_navigation_small_item_title); final ImageView icon = (ImageView) views.get(currentItem).findViewById(R.id.bottom_navigation_small_item_icon); + final TextView notification = (TextView) views.get(currentItem).findViewById(R.id.bottom_navigation_notification); - AHHelper.updateTopPadding(container, activePaddingTop, inactivePadding); + AHHelper.updateTopMargin(icon, activeMarginTop, inactiveMargin); + AHHelper.updateLeftMargin(notification, notificationActiveMarginLeft, notificationInactiveMarginLeft); AHHelper.updateTextColor(title, itemActiveColor, itemInactiveColor); AHHelper.updateAlpha(title, 1, 0); AHHelper.updateWidth(container, selectedItemWidth, notSelectedItemWidth); AHHelper.updateDrawableColor(context, items.get(currentItem).getDrawable(context), icon, itemActiveColor, itemInactiveColor, forceTint); + } } @@ -531,6 +562,68 @@ public class AHBottomNavigation extends FrameLayout { } } + /** + * Update notifications + */ + private void updateNotifications(boolean updateStyle) { + float textSize = getResources().getDimension(R.dimen.bottom_navigation_notification_text_size); + float textSizeMin = getResources().getDimension(R.dimen.bottom_navigation_notification_text_size_min); + for (int i = 0; i < views.size(); i++) { + TextView notification = (TextView) views.get(i).findViewById(R.id.bottom_navigation_notification); + if (updateStyle) { + notification.setTextColor(notificationTextColor); + if (notificationTypeface != null) { + notification.setTypeface(notificationTypeface); + } else { + notification.setTypeface(Typeface.DEFAULT); + } + + if (notificationBackgroundDrawable != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + notification.setBackground(notificationBackgroundDrawable); + } else { + notification.setBackgroundDrawable(notificationBackgroundDrawable); + } + } else if (notificationBackgroundColor != 0) { + Drawable defautlDrawable = ContextCompat.getDrawable(context, R.drawable.notification_background); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + notification.setBackground(AHHelper.getTintDrawable(defautlDrawable, + notificationBackgroundColor, forceTint)); + } else { + notification.setBackgroundDrawable(AHHelper.getTintDrawable(defautlDrawable, + notificationBackgroundColor, forceTint)); + } + } + } + + if (notifications[i] == 0 && notification.getText().length() > 0) { + notification.setText(""); + notification.animate() + .scaleX(0) + .scaleY(0) + .alpha(0) + .setDuration(150) + .start(); + } else if (notifications[i] > 0) { + if (notifications[i] >= 100) { + notification.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSizeMin); + notification.setText("99+"); + } else { + notification.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); + notification.setText(String.valueOf(notifications[i])); + } + notification.setScaleX(0); + notification.setScaleY(0); + notification.animate() + .scaleX(1) + .scaleY(1) + .alpha(1) + .setDuration(150) + .start(); + } + } + } + //////////// // PUBLIC // @@ -781,6 +874,73 @@ public class AHBottomNavigation extends FrameLayout { this.tabSelectedListener = null; } + /** + * Set the notification number + * @param nbNotification int + * @param itemPosition int + */ + public void setNotification(int nbNotification, int itemPosition) { + if (itemPosition < 0 || itemPosition > items.size() - 1) { + Log.w(TAG, "The position is out of bounds of the items (" + items.size() + " elements)"); + return; + } + notifications[itemPosition] = nbNotification; + updateNotifications(false); + } + + /** + * Set notification text color + * @param textColor int + */ + public void setNotificationTextColor(@ColorInt int textColor) { + notificationTextColor = textColor; + updateNotifications(true); + } + + /** + * Set notification text color + * @param textColor int + */ + public void setNotificationTextColorResource(@ColorRes int textColor) { + notificationTextColor = ContextCompat.getColor(context, textColor); + updateNotifications(true); + } + + /** + * Set notification background resource + * @param drawable Drawable + */ + public void setNotificationBackground(Drawable drawable) { + notificationBackgroundDrawable = drawable; + updateNotifications(true); + } + + /** + * Set notification background color + * @param color int + */ + public void setNotificationBackgroundColor(@ColorInt int color) { + notificationBackgroundColor = color; + updateNotifications(true); + } + + /** + * Set notification background color + * @param color int + */ + public void setNotificationBackgroundColorResource(@ColorRes int color) { + notificationBackgroundColor = ContextCompat.getColor(context, color); + updateNotifications(true); + } + + /** + * Set notification typeface + * @param typeface Typeface + */ + public void setNotificationBackgroundColorResource(Typeface typeface) { + notificationTypeface = typeface; + updateNotifications(true); + } //////////////// // INTERFACES // diff --git a/ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation/AHHelper.java b/ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation/AHHelper.java index f54dcfa..188f4e3 100644 --- a/ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation/AHHelper.java +++ b/ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation/AHHelper.java @@ -8,6 +8,7 @@ import android.content.ContextWrapper; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.os.Build; +import android.support.annotation.ColorInt; import android.support.v4.graphics.drawable.DrawableCompat; import android.util.DisplayMetrics; import android.util.TypedValue; @@ -31,32 +32,53 @@ public class AHHelper { * @param forceTint * @return */ - public static Drawable getTintDrawable(Drawable drawable, int color, boolean forceTint) { + public static Drawable getTintDrawable(Drawable drawable, @ColorInt int color, boolean forceTint) { if (forceTint) { drawable.clearColorFilter(); drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); drawable.invalidateSelf(); return drawable; } - Drawable wrapDrawable = DrawableCompat.wrap(drawable); + Drawable wrapDrawable = DrawableCompat.wrap(drawable).mutate(); DrawableCompat.setTint(wrapDrawable, color); return wrapDrawable; } /** - * Update top padding with animation + * Update top margin with animation */ - public static void updateTopPadding(final View view, int fromPadding, int toPadding) { - ValueAnimator animator = ValueAnimator.ofFloat(fromPadding, toPadding); + public static void updateTopMargin(final View view, int fromMargin, int toMargin) { + ValueAnimator animator = ValueAnimator.ofFloat(fromMargin, toMargin); animator.setDuration(150); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { float animatedValue = (float) valueAnimator.getAnimatedValue(); - view.setPadding(view.getPaddingLeft(), - (int) animatedValue, - view.getPaddingRight(), - view.getPaddingBottom()); + if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) { + ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams(); + p.setMargins(p.leftMargin, (int) animatedValue, p.rightMargin, p.bottomMargin); + view.requestLayout(); + } + } + }); + animator.start(); + } + + /** + * Update left margin with animation + */ + public static void updateLeftMargin(final View view, int fromMargin, int toMargin) { + ValueAnimator animator = ValueAnimator.ofFloat(fromMargin, toMargin); + animator.setDuration(150); + animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + float animatedValue = (float) valueAnimator.getAnimatedValue(); + if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) { + ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams(); + p.setMargins((int) animatedValue, p.topMargin, p.rightMargin, p.bottomMargin); + view.requestLayout(); + } } }); animator.start(); @@ -97,7 +119,8 @@ public class AHHelper { /** * Update text color with animation */ - public static void updateTextColor(final TextView textView, int fromColor, int toColor) { + public static void updateTextColor(final TextView textView, @ColorInt int fromColor, + @ColorInt int toColor) { ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), fromColor, toColor); colorAnimation.setDuration(150); colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @@ -112,7 +135,8 @@ public class AHHelper { /** * Update text color with animation */ - public static void updateViewBackgroundColor(final View view, int fromColor, int toColor) { + public static void updateViewBackgroundColor(final View view, @ColorInt int fromColor, + @ColorInt int toColor) { ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), fromColor, toColor); colorAnimation.setDuration(150); colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @@ -128,8 +152,8 @@ public class AHHelper { * Update image view color with animation */ public static void updateDrawableColor(final Context context, final Drawable drawable, - final ImageView imageView, int fromColor, int toColor, - final boolean forceTint) { + final ImageView imageView, @ColorInt int fromColor, + @ColorInt int toColor, final boolean forceTint) { ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), fromColor, toColor); colorAnimation.setDuration(150); colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |