diff --git a/.idea/modules.xml b/.idea/modules.xml index 7c640678..bb5dec50 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,8 +3,11 @@ + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/bottombar/sample/BadgeActivity.java b/app/src/main/java/com/example/bottombar/sample/BadgeActivity.java index dd6f41de..f8f71cb9 100644 --- a/app/src/main/java/com/example/bottombar/sample/BadgeActivity.java +++ b/app/src/main/java/com/example/bottombar/sample/BadgeActivity.java @@ -41,6 +41,6 @@ public void onTabReSelected(@IdRes int tabId) { }); BottomBarTab nearby = bottomBar.getTabWithId(R.id.tab_nearby); - nearby.setBadgeCount(5); + nearby.setBadgeCount(900); } } diff --git a/bottom-bar/src/androidTest/java/com/roughike/bottombar/BadgeTest.java b/bottom-bar/src/androidTest/java/com/roughike/bottombar/BadgeTest.java index df62e3ec..b84044d0 100644 --- a/bottom-bar/src/androidTest/java/com/roughike/bottombar/BadgeTest.java +++ b/bottom-bar/src/androidTest/java/com/roughike/bottombar/BadgeTest.java @@ -5,6 +5,7 @@ import android.support.test.annotation.UiThreadTest; import android.support.test.filters.LargeTest; import android.support.test.runner.AndroidJUnit4; +import android.text.TextUtils; import org.junit.Assert; import org.junit.Before; @@ -33,6 +34,7 @@ public void setUp() { bottomBar.setItems(com.roughike.bottombar.test.R.xml.dummy_tabs_three); nearby = bottomBar.getTabWithId(com.roughike.bottombar.test.R.id.tab_nearby); nearby.setBadgeCount(5); + nearby.setBadgeThreshold(20); } @Test @@ -95,4 +97,19 @@ public void badgeRemovedProperly() { assertNull(nearby.badge); assertEquals(bottomBar.findViewById(R.id.bb_bottom_bar_item_container), nearby.getOuterView()); } + + @Test + @UiThreadTest + public void badgeWithCounterBiggerThanThreshold(){ + nearby.setBadgeCount(25); + assertTrue(TextUtils.equals(nearby.badge.getText(), "20+")); + } + + @Test + @UiThreadTest + public void badgeWithCounterSmallerThanThreshold(){ + nearby.setBadgeCount(2); + assertTrue(TextUtils.equals(nearby.badge.getText(), "2")); + } + } diff --git a/bottom-bar/src/main/java/com/roughike/bottombar/BottomBar.java b/bottom-bar/src/main/java/com/roughike/bottombar/BottomBar.java index 350cc316..9d58d7cc 100644 --- a/bottom-bar/src/main/java/com/roughike/bottombar/BottomBar.java +++ b/bottom-bar/src/main/java/com/roughike/bottombar/BottomBar.java @@ -84,6 +84,7 @@ public class BottomBar extends LinearLayout implements View.OnClickListener, Vie private boolean showShadow; private float shadowElevation; private View shadowView; + private int badgeThreshold; private View backgroundOverlay; private ViewGroup outerContainer; @@ -212,6 +213,7 @@ private void populateAttributes(Context context, AttributeSet attrs, int defStyl titleTextAppearance = ta.getResourceId(R.styleable.BottomBar_bb_titleTextAppearance, 0); titleTypeFace = getTypeFaceFromAsset(ta.getString(R.styleable.BottomBar_bb_titleTypeFace)); showShadow = ta.getBoolean(R.styleable.BottomBar_bb_showShadow, true); + badgeThreshold = ta.getInt(R.styleable.BottomBar_bb_badgeThreshold, 99); } finally { ta.recycle(); } @@ -321,6 +323,7 @@ private BottomBarTab.Config getTabConfig() { .hideBadgeWhenSelected(hideBadgeWhenActive) .titleTextAppearance(titleTextAppearance) .titleTypeFace(titleTypeFace) + .setBadgeThreshold(badgeThreshold) .build(); } diff --git a/bottom-bar/src/main/java/com/roughike/bottombar/BottomBarBadge.java b/bottom-bar/src/main/java/com/roughike/bottombar/BottomBarBadge.java index af5b8546..d50857f6 100644 --- a/bottom-bar/src/main/java/com/roughike/bottombar/BottomBarBadge.java +++ b/bottom-bar/src/main/java/com/roughike/bottombar/BottomBarBadge.java @@ -5,9 +5,12 @@ import android.graphics.drawable.ShapeDrawable; import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; import android.support.annotation.VisibleForTesting; +import android.support.v4.content.ContextCompat; import android.support.v4.view.ViewCompat; import android.support.v7.widget.AppCompatImageView; +import android.support.v7.widget.AppCompatTextView; import android.view.Gravity; import android.view.ViewGroup; import android.view.ViewTreeObserver; @@ -29,12 +32,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -class BottomBarBadge extends TextView { +class BottomBarBadge extends AppCompatTextView { + private int count; private boolean isVisible = false; + private int countThreshold; + String countThresholdString; BottomBarBadge(Context context) { super(context); + countThresholdString = context.getString(R.string.badge_threshold); + } + + public void setCountThreshold(int countThreshold) { + this.countThreshold = countThreshold; } /** @@ -44,7 +55,12 @@ class BottomBarBadge extends TextView { */ void setCount(int count) { this.count = count; - setText(String.valueOf(count)); + + if(count > countThreshold){ + setText(String.format(countThresholdString, countThreshold)); + }else{ + setText(String.valueOf(count)); + } } /** diff --git a/bottom-bar/src/main/java/com/roughike/bottombar/BottomBarTab.java b/bottom-bar/src/main/java/com/roughike/bottombar/BottomBarTab.java index d33e1e30..54c950b5 100644 --- a/bottom-bar/src/main/java/com/roughike/bottombar/BottomBarTab.java +++ b/bottom-bar/src/main/java/com/roughike/bottombar/BottomBarTab.java @@ -68,6 +68,7 @@ public class BottomBarTab extends LinearLayout { private int indexInContainer; private int titleTextAppearanceResId; private Typeface titleTypeFace; + private int badgeThreshold; BottomBarTab(Context context) { super(context); @@ -87,6 +88,7 @@ void setConfig(@NonNull Config config) { setBadgeHidesWhenActive(config.badgeHidesWhenSelected); setTitleTextAppearance(config.titleTextAppearance); setTitleTypeface(config.titleTypeFace); + setBadgeThreshold(config.badgeThreshold); } void prepareLayout() { @@ -329,6 +331,7 @@ public void setBadgeCount(int count) { if (badge == null) { badge = new BottomBarBadge(getContext()); badge.attachToTab(this, badgeBackgroundColor); + badge.setCountThreshold(badgeThreshold); } badge.setCount(count); @@ -381,6 +384,18 @@ public Typeface getTitleTypeFace() { return titleTypeFace; } + public int getBadgeThreshold() { + return badgeThreshold; + } + + public void setBadgeThreshold(int badgeThreshold) { + this.badgeThreshold = badgeThreshold; + + if(badge != null){ + badge.setCountThreshold(badgeThreshold); + } + } + void select(boolean animate) { isActive = true; @@ -650,6 +665,7 @@ public static class Config { private final int titleTextAppearance; private final Typeface titleTypeFace; private boolean badgeHidesWhenSelected = true; + private final int badgeThreshold; private Config(Builder builder) { this.inActiveTabAlpha = builder.inActiveTabAlpha; @@ -661,6 +677,7 @@ private Config(Builder builder) { this.badgeHidesWhenSelected = builder.hidesBadgeWhenSelected; this.titleTextAppearance = builder.titleTextAppearance; this.titleTypeFace = builder.titleTypeFace; + this.badgeThreshold = builder.badgeThreshold; } public static class Builder { @@ -673,6 +690,7 @@ public static class Builder { private boolean hidesBadgeWhenSelected = true; private int titleTextAppearance; private Typeface titleTypeFace; + private int badgeThreshold; public Builder inActiveTabAlpha(float alpha) { this.inActiveTabAlpha = alpha; @@ -719,6 +737,11 @@ public Builder titleTypeFace(Typeface titleTypeFace) { return this; } + public Builder setBadgeThreshold(int badgeThreshold) { + this.badgeThreshold = badgeThreshold; + return this; + } + public Config build() { return new Config(this); } diff --git a/bottom-bar/src/main/res/values/attrs.xml b/bottom-bar/src/main/res/values/attrs.xml index 8b382f4d..c5f32702 100644 --- a/bottom-bar/src/main/res/values/attrs.xml +++ b/bottom-bar/src/main/res/values/attrs.xml @@ -19,5 +19,6 @@ + \ No newline at end of file diff --git a/bottom-bar/src/main/res/values/strings.xml b/bottom-bar/src/main/res/values/strings.xml index 88057c07..2f7035bc 100644 --- a/bottom-bar/src/main/res/values/strings.xml +++ b/bottom-bar/src/main/res/values/strings.xml @@ -1,3 +1,4 @@ BottomBar + %1$d+