aboutsummaryrefslogtreecommitdiffstats
path: root/ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation
diff options
context:
space:
mode:
authorAurelien Hubert <aurel.hubert@gmail.com>2016-03-25 19:28:42 +0100
committerAurelien Hubert <aurel.hubert@gmail.com>2016-03-25 19:28:42 +0100
commit3f0423373f85e34643d0eb1aa76d926ee408a22e (patch)
tree045d88cf2cf84f6acae11ee8823ac7ed08ff768b /ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation
parentee1a23bf7316a3d966e9552159ddce0f9284cf8f (diff)
downloadandroid_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.java214
-rw-r--r--ahbottomnavigation/src/main/java/com/aurelhubert/ahbottomnavigation/AHHelper.java50
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() {