package com.sxjs.common.widget.bottomnavigation; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.os.Build; import android.view.View; import android.view.ViewAnimationUtils; import android.widget.FrameLayout; import com.sxjs.common.R; /** * Class description : This is utils class specific for this library, most the common code goes here. * * @author ashokvarma * @version 1.0 * @since 19 Mar 2016 */ class BottomNavigationHelper { private BottomNavigationHelper() { } /** * Used to get Measurements for MODE_FIXED * * @param context to fetch measurements * @param screenWidth total screen width * @param noOfTabs no of bottom bar tabs * @param scrollable is bottom bar scrollable * @return width of each tab */ public static int[] getMeasurementsForFixedMode(Context context, int screenWidth, int noOfTabs, boolean scrollable) { int[] result = new int[2]; int minWidth = (int) context.getResources().getDimension(R.dimen.fixed_min_width_small_views); int maxWidth = (int) context.getResources().getDimension(R.dimen.fixed_min_width); int itemWidth = screenWidth / noOfTabs; if (itemWidth < minWidth && scrollable) { itemWidth = (int) context.getResources().getDimension(R.dimen.fixed_min_width); } else if (itemWidth > maxWidth) { itemWidth = maxWidth; } result[0] = itemWidth; return result; } /** * Used to get Measurements for MODE_SHIFTING * * @param context to fetch measurements * @param screenWidth total screen width * @param noOfTabs no of bottom bar tabs * @param scrollable is bottom bar scrollable * @return min and max width of each tab */ public static int[] getMeasurementsForShiftingMode(Context context, int screenWidth, int noOfTabs, boolean scrollable) { int[] result = new int[2]; int minWidth = (int) context.getResources().getDimension(R.dimen.shifting_min_width_inactive); int maxWidth = (int) context.getResources().getDimension(R.dimen.shifting_max_width_inactive); double minPossibleWidth = minWidth * (noOfTabs + 0.5); double maxPossibleWidth = maxWidth * (noOfTabs + 0.75); int itemWidth; int itemActiveWidth; if (screenWidth < minPossibleWidth) { if (scrollable) { itemWidth = minWidth; itemActiveWidth = (int) (minWidth * 1.5); } else { itemWidth = (int) (screenWidth / (noOfTabs + 0.5)); itemActiveWidth = (int) (itemWidth * 1.5); } } else if (screenWidth > maxPossibleWidth) { itemWidth = maxWidth; itemActiveWidth = (int) (itemWidth * 1.75); } else { double minPossibleWidth1 = minWidth * (noOfTabs + 0.625); double minPossibleWidth2 = minWidth * (noOfTabs + 0.75); itemWidth = (int) (screenWidth / (noOfTabs + 0.5)); itemActiveWidth = (int) (itemWidth * 1.5); if (screenWidth > minPossibleWidth1) { itemWidth = (int) (screenWidth / (noOfTabs + 0.625)); itemActiveWidth = (int) (itemWidth * 1.625); if (screenWidth > minPossibleWidth2) { itemWidth = (int) (screenWidth / (noOfTabs + 0.75)); itemActiveWidth = (int) (itemWidth * 1.75); } } } result[0] = itemWidth; result[1] = itemActiveWidth; return result; } /** * Used to get set data to the Tab views from navigation items * * @param bottomNavigationItem holds all the data * @param bottomNavigationTab view to which data need to be set * @param bottomNavigationBar view which holds all the tabs */ public static void bindTabWithData(BottomNavigationItem bottomNavigationItem, BottomNavigationTab bottomNavigationTab, BottomNavigationBar bottomNavigationBar) { Context context = bottomNavigationBar.getContext(); bottomNavigationTab.setLabel(bottomNavigationItem.getTitle(context)); bottomNavigationTab.setIcon(bottomNavigationItem.getIcon(context)); int activeColor = bottomNavigationItem.getActiveColor(context); int inActiveColor = bottomNavigationItem.getInActiveColor(context); if (activeColor != -1) { bottomNavigationTab.setActiveColor(activeColor); } else { bottomNavigationTab.setActiveColor(bottomNavigationBar.getActiveColor()); } if (inActiveColor != -1) { bottomNavigationTab.setInactiveColor(inActiveColor); } else { bottomNavigationTab.setInactiveColor(bottomNavigationBar.getInActiveColor()); } if (bottomNavigationItem.isInActiveIconAvailable()) { Drawable inactiveDrawable = bottomNavigationItem.getInactiveIcon(context); if (inactiveDrawable != null) { bottomNavigationTab.setInactiveIcon(inactiveDrawable); } } bottomNavigationTab.setItemBackgroundColor(bottomNavigationBar.getBackgroundColor()); setBadgeForTab(bottomNavigationItem.getBadgeItem(), bottomNavigationTab); } /** * Used to set badge for given tab * * @param badgeItem holds badge data * @param bottomNavigationTab bottom navigation tab to which badge needs to be attached */ private static void setBadgeForTab(BadgeItem badgeItem, BottomNavigationTab bottomNavigationTab) { if (badgeItem != null) { Context context = bottomNavigationTab.getContext(); GradientDrawable shape = getBadgeDrawable(badgeItem, context); bottomNavigationTab.badgeView.setBackgroundDrawable(shape); bottomNavigationTab.setBadgeItem(badgeItem); badgeItem.setTextView(bottomNavigationTab.badgeView); bottomNavigationTab.badgeView.setVisibility(View.VISIBLE); bottomNavigationTab.badgeView.setTextColor(badgeItem.getTextColor(context)); bottomNavigationTab.badgeView.setText(badgeItem.getText()); FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) bottomNavigationTab.badgeView.getLayoutParams(); layoutParams.gravity = badgeItem.getGravity(); bottomNavigationTab.badgeView.setLayoutParams(layoutParams); if(badgeItem.isHidden()){ // if hide is called before the initialisation of bottom-bar this will handle that // by hiding it. badgeItem.hide(); } } } static GradientDrawable getBadgeDrawable(BadgeItem badgeItem, Context context) { GradientDrawable shape = new GradientDrawable(); shape.setShape(GradientDrawable.RECTANGLE); shape.setCornerRadius(context.getResources().getDimensionPixelSize(R.dimen.badge_corner_radius)); shape.setColor(badgeItem.getBackgroundColor(context)); shape.setStroke(badgeItem.getBorderWidth(), badgeItem.getBorderColor(context)); return shape; } /** * Used to set the ripple animation when a tab is selected * * @param clickedView the view that is clicked (to get dimens where ripple starts) * @param backgroundView temporary view to which final background color is set * @param bgOverlay temporary view which is animated to get ripple effect * @param newColor the new color i.e ripple color * @param animationDuration duration for which animation runs */ public static void setBackgroundWithRipple(View clickedView, final View backgroundView, final View bgOverlay, final int newColor, int animationDuration) { int centerX = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { centerX = (int) (clickedView.getX() + (clickedView.getMeasuredWidth() / 2)); }else{ centerX = (int) (clickedView.getLeft() + (clickedView.getMeasuredWidth() / 2)); } int centerY = clickedView.getMeasuredHeight() / 2; int finalRadius = backgroundView.getWidth(); backgroundView.clearAnimation(); bgOverlay.clearAnimation(); Animator circularReveal = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { circularReveal = ViewAnimationUtils .createCircularReveal(bgOverlay, centerX, centerY, 0, finalRadius); } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { bgOverlay.setAlpha(0); circularReveal = ObjectAnimator.ofFloat(bgOverlay, "alpha", 0, 1); } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { circularReveal.setDuration(animationDuration); circularReveal.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { onCancel(); } @Override public void onAnimationCancel(Animator animation) { onCancel(); } private void onCancel() { backgroundView.setBackgroundColor(newColor); bgOverlay.setVisibility(View.GONE); } }); } bgOverlay.setBackgroundColor(newColor); bgOverlay.setVisibility(View.VISIBLE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { circularReveal.start(); } } }