diff --git a/README.md b/README.md
index 536d7f5..8df1eb7 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ dependencies {
Or Gradle Maven Central:
```groovy
-compile 'com.github.devlight.navigationtabbar:navigationtabbar:1.2.2'
+compile 'com.github.devlight.navigationtabbar:navigationtabbar:1.2.3'
```
Or Maven:
@@ -42,7 +42,7 @@ Or Maven:
com.github.devlight.navigationtabbar
navigationtabbar
- 1.2.2
+ 1.2.3
aar
```
@@ -71,9 +71,9 @@ For NTB you can set such parameters as:
allows you to connect NTB with ViewPager. If you want your can also set OnPageChangeListener.
- - background:
+ - background color:
- allows you to set background to NTB which automatically set with offset relative to badge gravity.
+ allows you to set background to NTB which automatically set with offset relative to badge gravity and corners radius.
- model selected icon:
@@ -95,13 +95,21 @@ For NTB you can set such parameters as:
allows you to handle mode of the model title show. Can show all or only active.
+ - title size:
+
+ allows you to set titles size.
+
- scale mode:
allows you to handle mode of the model icon and title scale.
- tint mode:
- allows you to enable or disable icon tinting.
+ allows you to enable or disable icon tinting.
+
+ - badge size:
+
+ allows you to set badges size.
- badge position:
@@ -153,12 +161,11 @@ You can set selected icon. Resize and scale of selected icon equals to original
Orientation automatically detected according to view size.
-By default badge bg color is the active model color and badge title color is the model bg color. To reset colors just set badge bg and title color to 0.
+By default badge bg color is the active model color and badge title color is the model bg color. To reset colors just set AUTO_COLOR value to badge bg and title color.
-If your set ViewPager you can action down on active pointer and do like drag.
-
-If you want to set the background to NTB, just set background via XML or code and its automatically set relative to badge gravity.
+By default badge sizes and title sizes is auto fit. To reset calculation just set AUTO_SIZE value to badge size and title size.
+If your set ViewPager and enable swipe you can action down on active pointer and do like drag.
Init
@@ -220,6 +227,10 @@ navigationTabBar.setIsTinted(true);
navigationTabBar.setIsBadgeUseTypeface(true);
navigationTabBar.setBadgeBgColor(Color.RED);
navigationTabBar.setBadgeTitleColor(Color.WHITE);
+navigationTabBar.setIsSwiped(true);
+navigationTabBar.setBgColor(Color.BLACK);
+navigationTabBar.setBadgeSize(10);
+navigationTabBar.setTitleSize(10);
```
If your models is in badge mode you can set title, hide, show, toggle and update badge title like this:
@@ -233,7 +244,12 @@ model.updateBadgeTitle("Here some title like NEW or some integer value");
To enable behavior translation inside CoordinatorLayout when at bottom of screen:
```java
-bottomNavigation.setBehaviorEnabled(true);
+navigationTabBar.setBehaviorEnabled(true);
+```
+
+To deselect active index and reset pointer:
+```java
+navigationTabBar.deselect();
```
Other methods check out in sample.
@@ -260,7 +276,11 @@ And XML init:
app:ntb_badge_bg_color="#ffff0000"
app:ntb_badge_title_color="#ffffffff"
app:ntb_typeface="fonts/custom_typeface.ttf"
- app:ntb_badge_use_typeface="true"/>
+ app:ntb_badge_use_typeface="true"
+ app:ntb_swiped="true"
+ app:ntb_bg_color="#000"
+ app:ntb_badge_size="10sp"
+ app:ntb_title_size="10sp"/>
```
Getting Help
diff --git a/app/build.gradle b/app/build.gradle
index 197f286..bbb740b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -22,6 +22,8 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':navigationtabbar')
+// compile 'com.github.devlight.navigationtabbar:navigationtabbar:1.2.2'
+
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:design:23.2.1'
compile 'com.android.support:support-v4:23.2.1'
diff --git a/app/src/main/java/com/gigamole/sample/HorizontalCoordinatorNtbActivity.java b/app/src/main/java/com/gigamole/sample/HorizontalCoordinatorNtbActivity.java
index 99d5277..e30618c 100644
--- a/app/src/main/java/com/gigamole/sample/HorizontalCoordinatorNtbActivity.java
+++ b/app/src/main/java/com/gigamole/sample/HorizontalCoordinatorNtbActivity.java
@@ -125,6 +125,22 @@ public void onEndTabSelected(final NavigationTabBar.Model model, final int index
model.hideBadge();
}
});
+ navigationTabBar.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+ @Override
+ public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
+
+ }
+
+ @Override
+ public void onPageSelected(final int position) {
+
+ }
+
+ @Override
+ public void onPageScrollStateChanged(final int state) {
+
+ }
+ });
final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.parent);
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
diff --git a/app/src/main/res/drawable/bg_round_circle.xml b/app/src/main/res/drawable/bg_round_circle.xml
deleted file mode 100644
index 5e40942..0000000
--- a/app/src/main/res/drawable/bg_round_circle.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_horizontal_coordinator_ntb.xml b/app/src/main/res/layout/activity_horizontal_coordinator_ntb.xml
index 46245b3..38aa002 100644
--- a/app/src/main/res/layout/activity_horizontal_coordinator_ntb.xml
+++ b/app/src/main/res/layout/activity_horizontal_coordinator_ntb.xml
@@ -58,7 +58,7 @@
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="bottom"
- android:background="#605271"
+ app:ntb_badge_size="12sp"
app:ntb_badge_bg_color="#ffff0000"
app:ntb_badge_gravity="top"
app:ntb_badge_position="left"
diff --git a/app/src/main/res/layout/activity_horizontal_ntb.xml b/app/src/main/res/layout/activity_horizontal_ntb.xml
index 9ee8419..1e719fa 100644
--- a/app/src/main/res/layout/activity_horizontal_ntb.xml
+++ b/app/src/main/res/layout/activity_horizontal_ntb.xml
@@ -4,6 +4,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ xmlns:tools="http://schemas.android.com/tools"
android:background="#423752"
android:orientation="vertical">
@@ -17,13 +18,13 @@
android:id="@+id/ntb_horizontal"
android:layout_width="match_parent"
android:layout_height="60dp"
- android:background="#605271"
app:ntb_badge_gravity="top"
app:ntb_badge_position="right"
app:ntb_badged="true"
app:ntb_scaled="true"
app:ntb_tinted="true"
app:ntb_title_mode="all"
- app:ntb_titled="true"/>
+ app:ntb_titled="true"
+ app:ntb_swiped="true"/>
diff --git a/app/src/main/res/layout/activity_horizontal_top_ntb.xml b/app/src/main/res/layout/activity_horizontal_top_ntb.xml
index 961ee00..ee6339e 100644
--- a/app/src/main/res/layout/activity_horizontal_top_ntb.xml
+++ b/app/src/main/res/layout/activity_horizontal_top_ntb.xml
@@ -24,11 +24,12 @@
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways">
-
@@ -62,6 +62,7 @@
android:layout_width="60dp"
android:layout_height="match_parent"
android:layout_gravity="center"
+ app:ntb_bg_color="#00000000"
app:ntb_corners_radius="10dp"
app:ntb_inactive_color="#000"
app:ntb_preview_colors="@array/red_wine"/>
@@ -88,6 +89,7 @@
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_gravity="center"
+ app:ntb_bg_color="#00FFFFFF"
app:ntb_active_color="#be7818"
app:ntb_inactive_color="#be7818"
app:ntb_animation_duration="1000"/>
@@ -105,13 +107,13 @@
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_gravity="center"
- android:background="@drawable/bg_round_circle"
app:ntb_animation_duration="400"
app:ntb_preview_colors="@array/red_wine"
- app:ntb_corners_radius="50dp"
+ app:ntb_corners_radius="25dp"
app:ntb_scaled="false"
app:ntb_active_color="#8d88e4"
- app:ntb_inactive_color="#dddfec"/>
+ app:ntb_inactive_color="#dddfec"
+ app:ntb_bg_color="#8d88e4"/>
@@ -126,7 +128,7 @@
android:layout_width="240dp"
android:layout_height="60dp"
android:layout_gravity="center"
- android:background="@drawable/bg_round_rect"
+ app:ntb_bg_color="#4b405c"
app:ntb_corners_radius="4dp"
app:ntb_preview_colors="@array/polluted_waves"/>
diff --git a/app/src/main/res/layout/activity_vertical_ntb.xml b/app/src/main/res/layout/activity_vertical_ntb.xml
index 7005fed..01bc3f0 100644
--- a/app/src/main/res/layout/activity_vertical_ntb.xml
+++ b/app/src/main/res/layout/activity_vertical_ntb.xml
@@ -10,7 +10,6 @@
diff --git a/navigationtabbar/build.gradle b/navigationtabbar/build.gradle
index 1313156..787c9da 100644
--- a/navigationtabbar/build.gradle
+++ b/navigationtabbar/build.gradle
@@ -19,7 +19,7 @@ apply plugin: "com.jfrog.bintray"
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'maven'
-version = "1.2.2"
+version = "1.2.3"
android {
compileSdkVersion 23
@@ -29,7 +29,7 @@ android {
minSdkVersion 11
targetSdkVersion 23
versionCode 1
- versionName "1.2.2"
+ versionName "1.2.3"
}
buildTypes {
release {
diff --git a/navigationtabbar/src/main/java/com/gigamole/navigationtabbar/ntb/NavigationTabBar.java b/navigationtabbar/src/main/java/com/gigamole/navigationtabbar/ntb/NavigationTabBar.java
index ad17d47..371f27b 100644
--- a/navigationtabbar/src/main/java/com/gigamole/navigationtabbar/ntb/NavigationTabBar.java
+++ b/navigationtabbar/src/main/java/com/gigamole/navigationtabbar/ntb/NavigationTabBar.java
@@ -45,6 +45,7 @@
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
@@ -68,15 +69,23 @@
public class NavigationTabBar extends View implements ViewPager.OnPageChangeListener {
// NTB constants
+ private final static int FLAGS =
+ Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG;
+
private final static String PREVIEW_BADGE = "0";
private final static String PREVIEW_TITLE = "Title";
+
private final static int INVALID_INDEX = -1;
+ public final static int AUTO_SIZE = -2;
+ public final static int AUTO_COLOR = -3;
private final static int DEFAULT_BADGE_ANIMATION_DURATION = 200;
private final static int DEFAULT_BADGE_REFRESH_ANIMATION_DURATION = 100;
private final static int DEFAULT_ANIMATION_DURATION = 300;
+
private final static int DEFAULT_INACTIVE_COLOR = Color.parseColor("#9f90af");
private final static int DEFAULT_ACTIVE_COLOR = Color.WHITE;
+ private final static int DEFAULT_BG_COLOR = Color.parseColor("#605271");
private final static float MIN_FRACTION = 0.0F;
private final static float NON_SCALED_FRACTION = 0.35F;
@@ -109,16 +118,12 @@ public class NavigationTabBar extends View implements ViewPager.OnPageChangeList
// NTB and pointer bounds
private final RectF mBounds = new RectF();
+ private final RectF mBgBounds = new RectF();
private final RectF mPointerBounds = new RectF();
// Badge bounds and bg badge bounds
private final Rect mBadgeBounds = new Rect();
private final RectF mBgBadgeBounds = new RectF();
- // NTB background
- private Bitmap mBackground;
- // Check whether need to reload background
- private boolean mNeedInvalidateBackground = true;
-
// Canvas, where all of other canvas will be merged
private Bitmap mBitmap;
private final Canvas mCanvas = new Canvas();
@@ -136,7 +141,6 @@ public class NavigationTabBar extends View implements ViewPager.OnPageChangeList
private final Canvas mPointerCanvas = new Canvas();
// External background view for the NTB
-// private View mBackgroundView = null;
private NavigationTabBarBehavior mBehavior;
// Detect if behavior already set
@@ -149,35 +153,30 @@ public class NavigationTabBar extends View implements ViewPager.OnPageChangeList
private boolean mAnimateHide;
// Main paint
- private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG) {
+ private final Paint mPaint = new Paint(FLAGS) {
+ {
+ setStyle(Style.FILL);
+ }
+ };
+ // Background color paint
+ private final Paint mBgPaint = new Paint(FLAGS) {
{
- setDither(true);
setStyle(Style.FILL);
}
};
-
// Pointer paint
- private final Paint mPointerPaint = new Paint(Paint.ANTI_ALIAS_FLAG) {
+ private final Paint mPointerPaint = new Paint(FLAGS) {
{
- setDither(true);
setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
}
};
// Icons paint
- private final Paint mIconPaint = new Paint(Paint.ANTI_ALIAS_FLAG) {
- {
- setDither(true);
- }
- };
- private final Paint mSelectedIconPaint = new Paint(Paint.ANTI_ALIAS_FLAG) {
- {
- setDither(true);
- }
- };
+ private final Paint mIconPaint = new Paint(FLAGS);
+ private final Paint mSelectedIconPaint = new Paint(FLAGS);
// Paint for icon mask pointer
- private final Paint mIconPointerPaint = new Paint(Paint.ANTI_ALIAS_FLAG) {
+ private final Paint mIconPointerPaint = new Paint(FLAGS) {
{
setStyle(Style.FILL);
setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
@@ -185,18 +184,16 @@ public class NavigationTabBar extends View implements ViewPager.OnPageChangeList
};
// Paint for model title
- private final Paint mModelTitlePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG) {
+ private final Paint mModelTitlePaint = new TextPaint(FLAGS) {
{
- setDither(true);
setColor(Color.WHITE);
setTextAlign(Align.CENTER);
}
};
// Paint for badge
- private final Paint mBadgePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG) {
+ private final Paint mBadgePaint = new TextPaint(FLAGS) {
{
- setDither(true);
setTextAlign(Align.CENTER);
setFakeBoldText(true);
}
@@ -226,12 +223,12 @@ public class NavigationTabBar extends View implements ViewPager.OnPageChangeList
private float mCornersRadius;
// Model title size and margin
- private float mModelTitleSize;
+ private float mModelTitleSize = AUTO_SIZE;
private float mTitleMargin;
// Model badge title size and margin
private float mBadgeMargin;
- private float mBadgeTitleSize;
+ private float mBadgeTitleSize = AUTO_SIZE;
// Model title mode: active ar all
private TitleMode mTitleMode;
@@ -242,9 +239,9 @@ public class NavigationTabBar extends View implements ViewPager.OnPageChangeList
// Model badge bg and title color.
// By default badge bg color is the active model color and badge title color is the model bg color
- // To reset colors just set bg and title color to 0
- private int mBadgeTitleColor;
- private int mBadgeBgColor;
+ // To reset colors just set bg and title color to AUTO_COLOR
+ private int mBadgeTitleColor = AUTO_COLOR;
+ private int mBadgeBgColor = AUTO_COLOR;
// Indexes
private int mLastIndex = INVALID_INDEX;
@@ -266,6 +263,8 @@ public class NavigationTabBar extends View implements ViewPager.OnPageChangeList
private boolean mIsScaled;
// Detect if model icon tinted
private boolean mIsTinted;
+ // Detect if model can swiped
+ private boolean mIsSwiped;
// Detect if model badge have custom typeface
private boolean mIsBadgeUseTypeface;
// Detect if is bar mode or indicator pager mode
@@ -284,6 +283,7 @@ public class NavigationTabBar extends View implements ViewPager.OnPageChangeList
// Color variables
private int mInactiveColor;
private int mActiveColor;
+ private int mBgColor;
// Custom typeface
private Typeface mTypeface;
@@ -296,14 +296,16 @@ public NavigationTabBar(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
+ @SuppressWarnings("ResourceAsColor")
public NavigationTabBar(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
//Init NTB
// Always draw
setWillNotDraw(false);
- // More speed!
- setLayerType(LAYER_TYPE_HARDWARE, null);
+ // Speed and fix for pre 17 API
+ ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, null);
+ setLayerType(LAYER_TYPE_SOFTWARE, null);
final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NavigationTabBar);
try {
@@ -311,6 +313,10 @@ public NavigationTabBar(final Context context, final AttributeSet attrs, final i
setIsBadged(typedArray.getBoolean(R.styleable.NavigationTabBar_ntb_badged, false));
setIsScaled(typedArray.getBoolean(R.styleable.NavigationTabBar_ntb_scaled, true));
setIsTinted(typedArray.getBoolean(R.styleable.NavigationTabBar_ntb_tinted, true));
+ setIsSwiped(typedArray.getBoolean(R.styleable.NavigationTabBar_ntb_swiped, true));
+ setTitleSize(
+ typedArray.getDimension(R.styleable.NavigationTabBar_ntb_title_size, AUTO_SIZE)
+ );
setIsBadgeUseTypeface(
typedArray.getBoolean(R.styleable.NavigationTabBar_ntb_badge_use_typeface, false)
);
@@ -320,6 +326,9 @@ public NavigationTabBar(final Context context, final AttributeSet attrs, final i
R.styleable.NavigationTabBar_ntb_title_mode, TitleMode.ALL_INDEX
)
);
+ setBadgeSize(
+ typedArray.getDimension(R.styleable.NavigationTabBar_ntb_badge_size, AUTO_SIZE)
+ );
setBadgePosition(
typedArray.getInt(
R.styleable.NavigationTabBar_ntb_badge_position, BadgePosition.RIGHT_INDEX
@@ -330,8 +339,12 @@ public NavigationTabBar(final Context context, final AttributeSet attrs, final i
R.styleable.NavigationTabBar_ntb_badge_gravity, BadgeGravity.TOP_INDEX
)
);
- setBadgeBgColor(typedArray.getColor(R.styleable.NavigationTabBar_ntb_badge_bg_color, 0));
- setBadgeTitleColor(typedArray.getColor(R.styleable.NavigationTabBar_ntb_badge_title_color, 0));
+ setBadgeBgColor(
+ typedArray.getColor(R.styleable.NavigationTabBar_ntb_badge_bg_color, AUTO_COLOR)
+ );
+ setBadgeTitleColor(
+ typedArray.getColor(R.styleable.NavigationTabBar_ntb_badge_title_color, AUTO_COLOR)
+ );
setTypeface(typedArray.getString(R.styleable.NavigationTabBar_ntb_typeface));
setInactiveColor(
@@ -344,6 +357,11 @@ public NavigationTabBar(final Context context, final AttributeSet attrs, final i
R.styleable.NavigationTabBar_ntb_active_color, DEFAULT_ACTIVE_COLOR
)
);
+ setBgColor(
+ typedArray.getColor(
+ R.styleable.NavigationTabBar_ntb_bg_color, DEFAULT_BG_COLOR
+ )
+ );
setAnimationDuration(
typedArray.getInteger(
R.styleable.NavigationTabBar_ntb_animation_duration, DEFAULT_ANIMATION_DURATION
@@ -458,6 +476,24 @@ public void setIsTinted(final boolean isTinted) {
updateTint();
}
+ public boolean isSwiped() {
+ return mIsSwiped;
+ }
+
+ public void setIsSwiped(final boolean swiped) {
+ mIsSwiped = swiped;
+ }
+
+ public float getTitleSize() {
+ return mModelTitleSize;
+ }
+
+ // To reset title size to automatic just put in method AUTO_SIZE value
+ public void setTitleSize(final float modelTitleSize) {
+ mModelTitleSize = modelTitleSize;
+ if (modelTitleSize == AUTO_SIZE) requestLayout();
+ }
+
public boolean isBadgeUseTypeface() {
return mIsBadgeUseTypeface;
}
@@ -547,6 +583,16 @@ public void setBadgeTitleColor(final int badgeTitleColor) {
mBadgeTitleColor = badgeTitleColor;
}
+ public float getBadgeSize() {
+ return mBadgeTitleSize;
+ }
+
+ // To reset badge title size to automatic just put in method AUTO_SIZE value
+ public void setBadgeSize(final float badgeTitleSize) {
+ mBadgeTitleSize = badgeTitleSize;
+ if (mBadgeTitleSize == AUTO_SIZE) requestLayout();
+ }
+
public Typeface getTypeface() {
return mTypeface;
}
@@ -602,6 +648,16 @@ public void setInactiveColor(final int inactiveColor) {
updateTint();
}
+ public int getBgColor() {
+ return mBgColor;
+ }
+
+ public void setBgColor(final int bgColor) {
+ mBgColor = bgColor;
+ mBgPaint.setColor(mBgColor);
+ postInvalidate();
+ }
+
public float getCornersRadius() {
return mCornersRadius;
}
@@ -678,6 +734,7 @@ public void setViewPager(final ViewPager viewPager) {
mIsViewPagerMode = true;
mViewPager = viewPager;
+ mViewPager.removeOnPageChangeListener(this);
mViewPager.addOnPageChangeListener(this);
resetScroller();
@@ -746,10 +803,8 @@ public void setModelIndex(int index, boolean force) {
// This check gives us opportunity to have an non selected model
if (mIndex == INVALID_INDEX) force = true;
-
// Detect if last is the same
- if (index == mIndex) return;
-
+ if (index == mIndex) force = true;
// Snap index to models size
index = Math.max(0, Math.min(index, mModels.size() - 1));
@@ -760,19 +815,40 @@ public void setModelIndex(int index, boolean force) {
mIsSetIndexFromTabBar = true;
if (mIsViewPagerMode) {
if (mViewPager == null) throw new IllegalStateException("ViewPager is null.");
- mViewPager.setCurrentItem(index, true);
+ mViewPager.setCurrentItem(index, !force);
}
// Set startX and endX for animation,
// where we animate two sides of rect with different interpolation
- mStartPointerX = mPointerLeftTop;
- mEndPointerX = mIndex * mModelSize;
+ if (force) {
+ mStartPointerX = mIndex * mModelSize;
+ mEndPointerX = mStartPointerX;
+ } else {
+ mStartPointerX = mPointerLeftTop;
+ mEndPointerX = mIndex * mModelSize;
+ }
// If it force, so update immediately, else animate
// This happens if we set index onCreate or something like this
// You can use force param or call this method in some post()
- if (force) updateIndicatorPosition(MAX_FRACTION);
- else mAnimator.start();
+ if (force) {
+ updateIndicatorPosition(MAX_FRACTION);
+ // Force onPageScrolled listener and refresh VP
+ if (mIsViewPagerMode) {
+ if (!mViewPager.isFakeDragging()) mViewPager.beginFakeDrag();
+ if (mViewPager.isFakeDragging()) mViewPager.fakeDragBy(0.0F);
+ if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
+ }
+ } else mAnimator.start();
+ }
+
+ // Deselect active index and reset pointer
+ public void deselect() {
+ mLastIndex = INVALID_INDEX;
+ mIndex = INVALID_INDEX;
+ mStartPointerX = INVALID_INDEX * mModelSize;
+ mEndPointerX = mStartPointerX;
+ updateIndicatorPosition(MIN_FRACTION);
}
private void updateIndicatorPosition(final float fraction) {
@@ -811,6 +887,7 @@ public boolean onTouchEvent(final MotionEvent event) {
// Action down touch
mIsActionDown = true;
if (!mIsViewPagerMode) break;
+ if (!mIsSwiped) break;
// Detect if we touch down on pointer, later to move
if (mIsHorizontalOrientation)
mIsPointerActionDown = (int) (event.getX() / mModelSize) == mIndex;
@@ -830,6 +907,7 @@ public boolean onTouchEvent(final MotionEvent event) {
case MotionEvent.ACTION_UP:
// Press up and set model index relative to current coordinate
if (mIsActionDown) {
+ playSoundEffect(SoundEffectConstants.CLICK);
if (mIsHorizontalOrientation) setModelIndex((int) (event.getX() / mModelSize));
else setModelIndex((int) (event.getY() / mModelSize));
}
@@ -868,12 +946,13 @@ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec
if (mIsBadged) side -= side * TITLE_SIZE_FRACTION;
mIconSize = side * (mIsTitled ? TITLE_ICON_SIZE_FRACTION : ICON_SIZE_FRACTION);
- mModelTitleSize = side * TITLE_SIZE_FRACTION;
+ if (mModelTitleSize == AUTO_SIZE) mModelTitleSize = side * TITLE_SIZE_FRACTION;
mTitleMargin = side * TITLE_MARGIN_FRACTION;
// If is badged mode, so get vars and set paint with default bounds
if (mIsBadged) {
- mBadgeTitleSize = mModelTitleSize * BADGE_TITLE_SIZE_FRACTION;
+ if (mBadgeTitleSize == AUTO_SIZE)
+ mBadgeTitleSize = (side * TITLE_SIZE_FRACTION) * BADGE_TITLE_SIZE_FRACTION;
final Rect badgeBounds = new Rect();
mBadgePaint.setTextSize(mBadgeTitleSize);
@@ -896,6 +975,9 @@ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec
// Set bounds for NTB
mBounds.set(0.0F, 0.0F, width, height - mBadgeMargin);
+ final float barBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : 0.0F;
+ mBgBounds.set(0.0F, barBadgeMargin, mBounds.width(), mBounds.height() + barBadgeMargin);
+
// Set main bitmap
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas.setBitmap(mBitmap);
@@ -955,51 +1037,11 @@ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec
setBehaviorEnabled(mBehaviorEnabled);
mIsBehaviorSet = true;
}
-
- if (mBackground == null || mNeedInvalidateBackground) {
- if (getBackground() != null) {
- if (getBackground() instanceof BitmapDrawable)
- mBackground = ((BitmapDrawable) getBackground()).getBitmap();
- else {
- mBackground = Bitmap.createBitmap(
- (int) mBounds.width(), (int) mBounds.height(), Bitmap.Config.ARGB_8888
- );
-
- final Canvas backgroundCanvas = new Canvas(mBackground);
- getBackground().setBounds(
- 0, 0, backgroundCanvas.getWidth(), backgroundCanvas.getHeight()
- );
- getBackground().draw(backgroundCanvas);
- }
-
- setBackgroundDrawable(null);
- mNeedInvalidateBackground = false;
- }
- }
- }
-
- @Override
- public void setBackgroundColor(final int color) {
- mNeedInvalidateBackground = true;
- super.setBackgroundColor(color);
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public void setBackgroundDrawable(final Drawable background) {
- mNeedInvalidateBackground = true;
- super.setBackgroundDrawable(background);
}
@SuppressWarnings("ConstantConditions")
@Override
protected void onDraw(final Canvas canvas) {
- if (mBackground != null)
- canvas.drawBitmap(
- mBackground, 0.0F,
- mBadgeGravity == BadgeGravity.TOP ? getBadgeMargin() : 0.0F, null
- );
-
if (mCanvas == null || mPointerCanvas == null ||
mIconsCanvas == null || mTitlesCanvas == null)
return;
@@ -1010,8 +1052,11 @@ protected void onDraw(final Canvas canvas) {
mIconsCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
if (mIsTitled) mTitlesCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ if (mCornersRadius == 0) canvas.drawRect(mBgBounds, mBgPaint);
+ else canvas.drawRoundRect(mBgBounds, mCornersRadius, mCornersRadius, mBgPaint);
+
// Get pointer badge margin for gravity
- final float pointerBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : 0.0F;
+ final float barBadgeMargin = mBadgeGravity == BadgeGravity.TOP ? mBadgeMargin : 0.0F;
// Draw our model colors
for (int i = 0; i < mModels.size(); i++) {
@@ -1021,7 +1066,7 @@ protected void onDraw(final Canvas canvas) {
final float left = mModelSize * i;
final float right = left + mModelSize;
mCanvas.drawRect(
- left, pointerBadgeMargin, right, mBounds.height() + pointerBadgeMargin, mPaint
+ left, barBadgeMargin, right, mBounds.height() + barBadgeMargin, mPaint
);
} else {
final float top = mModelSize * i;
@@ -1033,8 +1078,8 @@ protected void onDraw(final Canvas canvas) {
// Set bound of pointer
if (mIsHorizontalOrientation)
mPointerBounds.set(
- mPointerLeftTop, pointerBadgeMargin,
- mPointerRightBottom, mBounds.height() + pointerBadgeMargin
+ mPointerLeftTop, barBadgeMargin,
+ mPointerRightBottom, mBounds.height() + barBadgeMargin
);
else mPointerBounds.set(0.0F, mPointerLeftTop, mBounds.width(), mPointerRightBottom);
@@ -1126,12 +1171,7 @@ else if (mLastIndex == i)
matrixScale, matrixCenterX, matrixCenterY
);
} else {
- if (i != mIndex && i != mIndex + 1)
- updateInactiveModel(
- model, leftOffset, topOffset, titleScale,
- matrixScale, matrixCenterX, matrixCenterY
- );
- else if (i == mIndex + 1)
+ if (i == mIndex + 1)
updateCurrentModel(
model, leftOffset, topOffset, titleTranslate, interpolation,
matrixCenterX, matrixCenterY, matrixScale, titleScale, titleAlpha
@@ -1141,6 +1181,11 @@ else if (i == mIndex)
model, leftOffset, topOffset, titleTranslate, lastInterpolation,
matrixCenterX, matrixCenterY, matrixLastScale, titleLastScale, titleLastAlpha
);
+ else
+ updateInactiveModel(
+ model, leftOffset, topOffset, titleScale,
+ matrixScale, matrixCenterX, matrixCenterY
+ );
}
// Draw original model icon
@@ -1187,9 +1232,9 @@ else if (i == mIndex)
// Draw general bitmap
canvas.drawBitmap(mBitmap, 0.0F, 0.0F, null);
// Draw icons bitmap on top
- canvas.drawBitmap(mIconsBitmap, 0.0F, pointerBadgeMargin, null);
+ canvas.drawBitmap(mIconsBitmap, 0.0F, barBadgeMargin, null);
// Draw titles bitmap on top
- if (mIsTitled) canvas.drawBitmap(mTitlesBitmap, 0.0F, pointerBadgeMargin, null);
+ if (mIsTitled) canvas.drawBitmap(mTitlesBitmap, 0.0F, barBadgeMargin, null);
// If is not badged, exit
if (!mIsBadged) return;
@@ -1240,7 +1285,7 @@ else if (i == mIndex)
// Set color and alpha for badge bg
if (model.mBadgeFraction == MIN_FRACTION) mBadgePaint.setColor(Color.TRANSPARENT);
- else mBadgePaint.setColor(mBadgeBgColor == 0 ? mActiveColor : mBadgeBgColor);
+ else mBadgePaint.setColor(mBadgeBgColor == AUTO_COLOR ? mActiveColor : mBadgeBgColor);
mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));
// Set corners to round rect for badge bg and draw
@@ -1250,7 +1295,7 @@ else if (i == mIndex)
// Set color and alpha for badge title
if (model.mBadgeFraction == MIN_FRACTION) mBadgePaint.setColor(Color.TRANSPARENT);
else //noinspection ResourceAsColor
- mBadgePaint.setColor(mBadgeTitleColor == 0 ? model.getColor() : mBadgeTitleColor);
+ mBadgePaint.setColor(mBadgeTitleColor == AUTO_COLOR ? model.getColor() : mBadgeTitleColor);
mBadgePaint.setAlpha((int) (MAX_ALPHA * model.mBadgeFraction));
// Set badge title center position and draw title
@@ -1426,6 +1471,11 @@ private void updateTint() {
@Override
public void onPageScrolled(int position, float positionOffset, final int positionOffsetPixels) {
+ //Fix the wrong position problem for some devices
+ position = position + (int) positionOffset;
+ if (mOnPageChangeListener != null)
+ mOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
+
// If we animate, don`t call this
if (!mIsSetIndexFromTabBar) {
mIsResizeIn = position < mIndex;
@@ -1437,35 +1487,26 @@ public void onPageScrolled(int position, float positionOffset, final int positio
updateIndicatorPosition(positionOffset);
}
- if (mOnPageChangeListener != null)
- mOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
+ // Stop scrolling on animation end and reset values
+ if (!mAnimator.isRunning() && mIsSetIndexFromTabBar) {
+ mFraction = MIN_FRACTION;
+ mIsSetIndexFromTabBar = false;
+ }
}
@Override
public void onPageSelected(final int position) {
- // If VP idle, so update
- if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
- mIsResizeIn = position < mIndex;
- mLastIndex = mIndex;
- mIndex = position;
- postInvalidate();
- }
}
@Override
public void onPageScrollStateChanged(final int state) {
// If VP idle, reset to MIN_FRACTION
+ mScrollState = state;
if (state == ViewPager.SCROLL_STATE_IDLE) {
- mFraction = MIN_FRACTION;
- mIsSetIndexFromTabBar = false;
-
if (mOnPageChangeListener != null) mOnPageChangeListener.onPageSelected(mIndex);
- else {
- if (mOnTabBarSelectedIndexListener != null)
- mOnTabBarSelectedIndexListener.onEndTabSelected(mModels.get(mIndex), mIndex);
- }
+ if (mIsViewPagerMode && mOnTabBarSelectedIndexListener != null)
+ mOnTabBarSelectedIndexListener.onEndTabSelected(mModels.get(mIndex), mIndex);
}
- mScrollState = state;
if (mOnPageChangeListener != null) mOnPageChangeListener.onPageScrollStateChanged(state);
}
@@ -1527,7 +1568,7 @@ protected void onConfigurationChanged(final Configuration newConfig) {
// Refresh pointer and state after config changed to current
final int tempIndex = mIndex;
- setModelIndex(INVALID_INDEX, true);
+ deselect();
post(new Runnable() {
@Override
public void run() {
@@ -1828,7 +1869,6 @@ public float getResizeInterpolation(final float input, final boolean resizeIn) {
// Model title mode
public enum TitleMode {
-
ALL, ACTIVE;
public final static int ALL_INDEX = 0;
@@ -1837,7 +1877,6 @@ public enum TitleMode {
// Model badge position
public enum BadgePosition {
-
LEFT(LEFT_FRACTION), CENTER(CENTER_FRACTION), RIGHT(RIGHT_FRACTION);
public final static int LEFT_INDEX = 0;
@@ -1857,7 +1896,6 @@ public enum BadgePosition {
// Model badge gravity
public enum BadgeGravity {
-
TOP, BOTTOM;
public final static int TOP_INDEX = 0;
diff --git a/navigationtabbar/src/main/res/values/attrs.xml b/navigationtabbar/src/main/res/values/attrs.xml
index 13ca302..f59d52f 100644
--- a/navigationtabbar/src/main/res/values/attrs.xml
+++ b/navigationtabbar/src/main/res/values/attrs.xml
@@ -6,12 +6,16 @@
+
+
+
+
@@ -30,6 +34,7 @@
+