diff --git a/README.md b/README.md index fa80fd2..6f4be5c 100644 --- a/README.md +++ b/README.md @@ -12,30 +12,27 @@ An android lib for enhancing BottomNavigationView. ## Feature ## -- ### getCurrentItem ### - Get current checked item - -- ### setCurrentItem ### - Set current checked item - -- ### enableShiftingMode ### - Open or close shifting mode for navigation bar - -- ### enableItemShiftingMode ### - Open or close shifting mode for menu item - -- ### enableAnimation ### - Open or close animation for menu item - -- ### setTextVisibility ### - Set the visibility of text - -- ### setIconVisibility ### - Set the visibility of icon +|methods|description +|---|---| +|enableAnimation|Enable or disable click item animation(text scale and icon move animation in no item shifting mode). Default true. +|enableItemShiftingMode|Enable the shifting mode for each item. It will has a shift animation for item if true. Otherwise the item text always be shown. Default true when item count > 3. +|enableShiftingMode|Enable the shifting mode for navigation. It will has a shift animation if true. Otherwise all items are the same width. Default true when item count > 3. +|getBottomNavigationItemView|Get private mButton in mMenuView at position +|getBottomNavigationItemViews|Get private mButtons in mMenuView +|getCurrentItem|Get the current checked item position. +|getIconAt|Get icon at position. +|getMenuItemPosition|Get menu item position in menu. Return position if success, -1 otherwise. +|getOnNavigationItemSelectedListener|Get OnNavigationItemSelectedListener. +|setCurrentItem|Set the current checked item. +|setIconVisibility|Change the visibility of icon. +|setTextVisibility|Change the visibility of text. +|setupWithViewPager|This method will link the given ViewPager and this BottomNavigationViewEx together so that changes in one are automatically reflected in the other. This includes scroll state changes and clicks. ## Example ## +**Style** + ![](/read_me_images/normal.gif) ![](/read_me_images/no_animation.gif) @@ -68,6 +65,9 @@ An android lib for enhancing BottomNavigationView. ![](/read_me_images/with_view_pager.gif) +**Add ViewBadger** + +![](/read_me_images/view_badger.gif) ## Adding to project ## @@ -75,7 +75,7 @@ An android lib for enhancing BottomNavigationView. `compileSdkVersion` >= 25 and add `design` : ``` -compile 'com.android.support:design:25.0.0' +compile 'com.android.support:design:25.0.1' ``` ### Importing to project ### @@ -94,7 +94,7 @@ allprojects { Step 2. Add the dependency ``` -compile 'com.github.ittianyu:BottomNavigationViewEx:1.1.0' +compile 'com.github.ittianyu:BottomNavigationViewEx:1.1.1' ``` #### and for Maven: #### @@ -114,7 +114,7 @@ Step 2. Add the dependency com.github.ittianyu BottomNavigationViewEx - 1.1.0 + 1.1.1 ``` @@ -126,7 +126,6 @@ Downloading [BottomNavigationViewEx.java](https://raw.githubusercontent.com/itti ## Getting started ## Adding a custom widget in `xml` : - ```xml ``` -Binding view in `Activity` and setting style: - +Binding view in `Activity`: ```java BottomNavigationViewEx bnve = (BottomNavigationViewEx) findViewById(R.id.bnve); +``` +#### Disable all animations #### +```java bnve.enableAnimation(false); - bnve.enableShiftingMode(false); - bnve.enableItemShiftingMode(false); +``` -bnve.setTextVisibility(false); - -bnve.setIconVisibility(false); - -bnve.setCurrentItem(1); +#### Binding with ViewPager #### +```java +// set adapter +adapter = new VpAdapter(getSupportFragmentManager(), fragments); +bind.vp.setAdapter(adapter); -bnve.getCurrentItem(); +// binding with ViewPager +bind.bnve.setupWithViewPager(bind.vp); ``` +#### Other usage in BottomNavigationViewEx #### +You can see the demo. + +#### Usage in BottomNavigationView #### Other usage is the same as official `BottomNavigationView`. You can [click here](https://developer.android.com/reference/android/support/design/widget/BottomNavigationView.html) for detail. + ## References ## The lib is based on `BottomNavigationView` in `Support Library 25 design`. @@ -214,30 +220,27 @@ You no need to worry about stability. Because I minimise modifying by reflecting ## 功能 ## -- ### getCurrentItem ### - 获取当前选中的项 - -- ### setCurrentItem ### - 设置当前选中的项 - -- ### enableShiftingMode ### - 开启或关闭导航条的位移模式 - -- ### enableItemShiftingMode ### - 开启或关闭子菜单的位移模式 - -- ### enableAnimation ### - 开启或关闭子菜单的文字和图片动画 - -- ### setTextVisibility ### - 设置子菜单文本可见性 - -- ### setIconVisibility ### - 设置子菜单图片可见性 +|methods|description +|---|---| +|enableAnimation|开启或关闭点击动画(文字放大效果和图片移动效果)。 默认为 true. +|enableItemShiftingMode|开始或关闭子菜单位移模式。 如果为 true,除了当前选中项,其他项的文本将会隐藏。 当菜单数大于3时,默认为 true。 +|enableShiftingMode|开始或关闭导航条位移模式。如果为 true,选中项和其他项的宽度不一样。当菜单数大于3时,默认为 true。 +|getBottomNavigationItemView|获取位于 position 的私有成员变量 mButton。 +|getBottomNavigationItemViews|获取私有成员变量 mButtons。 +|getCurrentItem|获取当前选中项的索引。 +|getIconAt|获取位于 position 的图片. +|getMenuItemPosition|获取子菜单的索引。如果找不到,返回 -1。 +|getOnNavigationItemSelectedListener|获取 OnNavigationItemSelectedListener。 +|setCurrentItem|设置当前选中项。 +|setIconVisibility|设置图片可见性。 +|setTextVisibility|设置文本可见性。 +|setupWithViewPager|和 ViewPager 绑定,当 任何一个选中项改变时,都会自动改变另一项。 ## 例子 ## +**样式** + ![](/read_me_images/normal.gif) ![](/read_me_images/no_animation.gif) @@ -266,10 +269,15 @@ You no need to worry about stability. Because I minimise modifying by reflecting ![](/read_me_images/no_animation_shifting_mode_item_shifting_mode_icon.gif) -**With ViewPager** +**和 ViewPager 一起使用** ![](/read_me_images/with_view_pager.gif) +**带数字的小红圈** + +![](/read_me_images/view_badger.gif) + + ## 加入工程 ## @@ -277,7 +285,7 @@ You no need to worry about stability. Because I minimise modifying by reflecting `compileSdkVersion` >= 25 且添加 `design` 依赖包: ``` -compile 'com.android.support:design:25.0.0' +compile 'com.android.support:design:25.0.1' ``` ### 导入本库 ### @@ -296,7 +304,7 @@ allprojects { 步骤 2. 添加依赖 ``` -compile 'com.github.ittianyu:BottomNavigationViewEx:1.1.0' +compile 'com.github.ittianyu:BottomNavigationViewEx:1.1.1' ``` #### Maven例子: #### @@ -316,7 +324,7 @@ compile 'com.github.ittianyu:BottomNavigationViewEx:1.1.0' com.github.ittianyu BottomNavigationViewEx - 1.1.0 + 1.1.1 ``` @@ -327,8 +335,8 @@ compile 'com.github.ittianyu:BottomNavigationViewEx:1.1.0' ## 开始使用 ## -在 `xml` 布局中添加自定义控件: +在 `xml` 布局中添加自定义控件: ```xml ``` -在 `Activity` 中绑定控件,并设置样式: - +在 `Activity` 中绑定控件: ```java BottomNavigationViewEx bnve = (BottomNavigationViewEx) findViewById(R.id.bnve); +``` +#### 禁止所有动画效果 #### +```java bnve.enableAnimation(false); - bnve.enableShiftingMode(false); - bnve.enableItemShiftingMode(false); +``` -bnve.setTextVisibility(false); - -bnve.setIconVisibility(false); - -bnve.setCurrentItem(1); +#### 和 ViewPager 绑定#### +```java +// set adapter +adapter = new VpAdapter(getSupportFragmentManager(), fragments); +bind.vp.setAdapter(adapter); -bnve.getCurrentItem(); +// binding with ViewPager +bind.bnve.setupWithViewPager(bind.vp); ``` +#### 其他 BottomNavigationViewEx 的用法 #### +请参考demo。 + +#### 其他 BottomNavigationView 的用法 #### 其他用法和官方 `BottomNavigationView` 一样。 详情[点击这里](https://developer.android.com/reference/android/support/design/widget/BottomNavigationView.html) diff --git a/app/build.gradle b/app/build.gradle index 7621a17..744771a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -31,4 +31,5 @@ dependencies { compile 'com.android.support:design:25.0.1' testCompile 'junit:junit:4.12' compile project(':widget') + compile files('libs/android-viewbadger.jar') } diff --git a/app/libs/android-viewbadger.jar b/app/libs/android-viewbadger.jar new file mode 100644 index 0000000..f604751 Binary files /dev/null and b/app/libs/android-viewbadger.jar differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 67281d9..df72427 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,15 +8,21 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> - + - - + + + + \ No newline at end of file diff --git a/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/viewpager/BaseFragment.java b/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/BaseFragment.java similarity index 94% rename from app/src/main/java/com/ittianyu/bottomnavigationviewexsample/viewpager/BaseFragment.java rename to app/src/main/java/com/ittianyu/bottomnavigationviewexsample/BaseFragment.java index 9ad5827..929835d 100644 --- a/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/viewpager/BaseFragment.java +++ b/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/BaseFragment.java @@ -1,4 +1,4 @@ -package com.ittianyu.bottomnavigationviewexsample.viewpager; +package com.ittianyu.bottomnavigationviewexsample; import android.databinding.DataBindingUtil; import android.os.Bundle; diff --git a/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/MainActivity.java b/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/MainActivity.java index 19cc2ed..2081333 100644 --- a/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/MainActivity.java +++ b/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/MainActivity.java @@ -7,7 +7,9 @@ import android.view.View; import com.ittianyu.bottomnavigationviewexsample.databinding.ActivityMainBinding; +import com.ittianyu.bottomnavigationviewexsample.setupwithviewpager.SetupWithViewPagerActivity; import com.ittianyu.bottomnavigationviewexsample.style.StyleActivity; +import com.ittianyu.bottomnavigationviewexsample.viewbadger.ViewBadgerActivity; import com.ittianyu.bottomnavigationviewexsample.viewpager.WithViewPagerActivity; public class MainActivity extends AppCompatActivity implements View.OnClickListener { @@ -25,6 +27,8 @@ protected void onCreate(Bundle savedInstanceState) { private void init() { binding.btnStyle.setOnClickListener(this); binding.btnWithViewPager.setOnClickListener(this); + binding.btnSetupWithViewPager.setOnClickListener(this); + binding.btnViewBadger.setOnClickListener(this); } @@ -37,6 +41,13 @@ public void onClick(View view) { case R.id.btn_with_view_pager: startActivity(new Intent(this, WithViewPagerActivity.class)); break; + case R.id.btn_setup_with_view_pager: + startActivity(new Intent(this, SetupWithViewPagerActivity.class)); + break; + case R.id.btn_view_badger: + startActivity(new Intent(this, ViewBadgerActivity.class)); + break; + } } } diff --git a/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/setupwithviewpager/SetupWithViewPagerActivity.java b/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/setupwithviewpager/SetupWithViewPagerActivity.java new file mode 100644 index 0000000..decf9a2 --- /dev/null +++ b/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/setupwithviewpager/SetupWithViewPagerActivity.java @@ -0,0 +1,123 @@ +package com.ittianyu.bottomnavigationviewexsample.setupwithviewpager; + +import android.databinding.DataBindingUtil; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.design.widget.BottomNavigationView; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.MenuItem; + +import com.ittianyu.bottomnavigationviewexsample.BaseFragment; +import com.ittianyu.bottomnavigationviewexsample.R; +import com.ittianyu.bottomnavigationviewexsample.databinding.ActivityWithViewPagerBinding; + +import java.util.ArrayList; +import java.util.List; + +public class SetupWithViewPagerActivity extends AppCompatActivity { + private static final String TAG = SetupWithViewPagerActivity.class.getSimpleName(); + private ActivityWithViewPagerBinding bind; + private VpAdapter adapter; + + // collections + private List fragments;// used for ViewPager adapter + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); +// setContentView(R.layout.activity_with_view_pager); + bind = DataBindingUtil.setContentView(this, R.layout.activity_with_view_pager); + + initView(); + initData(); + initEvent(); + } + + /** + * change BottomNavigationViewEx style + */ + private void initView() { + bind.bnve.enableItemShiftingMode(true); + bind.bnve.enableAnimation(false); + } + + /** + * create fragments + */ + private void initData() { + fragments = new ArrayList<>(3); + + // create music fragment and add it + BaseFragment musicFragment = new BaseFragment(); + Bundle bundle = new Bundle(); + bundle.putString("title", getString(R.string.music)); + musicFragment.setArguments(bundle); + + // create backup fragment and add it + BaseFragment backupFragment = new BaseFragment(); + bundle = new Bundle(); + bundle.putString("title", getString(R.string.backup)); + backupFragment.setArguments(bundle); + + // create friends fragment and add it + BaseFragment friendsFragment = new BaseFragment(); + bundle = new Bundle(); + bundle.putString("title", getString(R.string.friends)); + friendsFragment.setArguments(bundle); + + // add to fragments for adapter + fragments.add(musicFragment); + fragments.add(backupFragment); + fragments.add(friendsFragment); + + // set adapter + adapter = new VpAdapter(getSupportFragmentManager(), fragments); + bind.vp.setAdapter(adapter); + + // binding with ViewPager + bind.bnve.setupWithViewPager(bind.vp); + } + + /** + * set listeners + */ + private void initEvent() { + // set listener to do something then item selected + bind.bnve.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + Log.d(TAG, item.getItemId() + " item was selected-------------------"); + // you can return false to cancel select + return true; + } + }); + + } + + /** + * view pager adapter + */ + private static class VpAdapter extends FragmentPagerAdapter { + private List data; + + public VpAdapter(FragmentManager fm, List data) { + super(fm); + this.data = data; + } + + @Override + public int getCount() { + return data.size(); + } + + @Override + public Fragment getItem(int position) { + return data.get(position); + } + } + +} diff --git a/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/viewbadger/ViewBadgerActivity.java b/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/viewbadger/ViewBadgerActivity.java new file mode 100644 index 0000000..cb42c5b --- /dev/null +++ b/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/viewbadger/ViewBadgerActivity.java @@ -0,0 +1,90 @@ +package com.ittianyu.bottomnavigationviewexsample.viewbadger; + +import android.databinding.DataBindingUtil; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.design.widget.BottomNavigationView; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatActivity; +import android.view.MenuItem; +import android.widget.ImageView; + +import com.ittianyu.bottomnavigationviewexsample.R; +import com.ittianyu.bottomnavigationviewexsample.databinding.ActivityViewBadgerBinding; +import com.readystatesoftware.viewbadger.BadgeView; + +public class ViewBadgerActivity extends AppCompatActivity { + private ActivityViewBadgerBinding bind; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); +// setContentView(R.layout.activity_view_badger); + bind = DataBindingUtil.setContentView(this, R.layout.activity_view_badger); + + initView(); + } + + private void initView() { + // disable all animations + bind.bnve.enableAnimation(false); + bind.bnve.enableShiftingMode(false); + bind.bnve.enableItemShiftingMode(false); + + // add a BadgeView at second icon + bind.bnve.post(new Runnable() { + @Override + public void run() { + final BadgeView badgeView1 = addBadgeViewAt(1, "1"); + final BadgeView badgeView3 = addBadgeViewAt(3, "99"); + + // hide the red circle when click + bind.bnve.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + int position = bind.bnve.getMenuItemPosition(item); + switch (position) { + case 1: + badgeView1.toggle(true); + break; + case 3: + badgeView3.toggle(true); + break; + } + return true; + } + }); + } + }); + } + + /** + * add a BadgeView on icon at position + * @param position + * @return + */ + private BadgeView addBadgeViewAt(int position, String text) { + // get position + ImageView icon = bind.bnve.getIconAt(position); + int[] pos = new int[2]; + icon.getLocationInWindow(pos); + // action bar height + ActionBar actionBar = getSupportActionBar(); + int actionBarHeight = 0; + if (null != actionBar) { + actionBarHeight = actionBar.getHeight(); + } + int x = (int) (pos[0] + icon.getMeasuredWidth() * 0.8f); + int y = (int) (pos[1] - actionBarHeight - icon.getMeasuredHeight() * 1.2f); + + // create BadgeView: detail for BadgeView click here + // https://github.com/jgilfelt/android-viewbadger + BadgeView badge = new BadgeView(ViewBadgerActivity.this, bind.rlRoot); + badge.setText(text); + badge.setBadgePosition(BadgeView.POSITION_TOP_LEFT); + badge.setBadgeMargin(x, y); + badge.show(); + + return badge; + } +} diff --git a/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/viewpager/WithViewPagerActivity.java b/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/viewpager/WithViewPagerActivity.java index d0fa91d..4d8e8c7 100644 --- a/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/viewpager/WithViewPagerActivity.java +++ b/app/src/main/java/com/ittianyu/bottomnavigationviewexsample/viewpager/WithViewPagerActivity.java @@ -13,6 +13,7 @@ import android.util.SparseArray; import android.view.MenuItem; +import com.ittianyu.bottomnavigationviewexsample.BaseFragment; import com.ittianyu.bottomnavigationviewexsample.R; import com.ittianyu.bottomnavigationviewexsample.databinding.ActivityWithViewPagerBinding; @@ -20,12 +21,12 @@ import java.util.List; public class WithViewPagerActivity extends AppCompatActivity { - private static final String TAG = WithViewPagerActivity.class.getCanonicalName(); + private static final String TAG = WithViewPagerActivity.class.getSimpleName(); private ActivityWithViewPagerBinding bind; private VpAdapter adapter; // collections - private SparseArray fragmentMap;// used for change ViewPager selected item + private SparseArray items;// used for change ViewPager selected item private List fragments;// used for ViewPager adapter @Override @@ -52,7 +53,7 @@ private void initView() { */ private void initData() { fragments = new ArrayList<>(3); - fragmentMap = new SparseArray<>(3); + items = new SparseArray<>(3); // create music fragment and add it BaseFragment musicFragment = new BaseFragment(); @@ -77,10 +78,10 @@ private void initData() { fragments.add(backupFragment); fragments.add(friendsFragment); - // add to fragmentMap for change ViewPager item - fragmentMap.put(R.id.menu_music, 0); - fragmentMap.put(R.id.menu_backup, 1); - fragmentMap.put(R.id.menu_friends, 2); + // add to items for change ViewPager item + items.put(R.id.menu_music, 0); + items.put(R.id.menu_backup, 1); + items.put(R.id.menu_friends, 2); // set adapter adapter = new VpAdapter(getSupportFragmentManager(), fragments); @@ -93,6 +94,8 @@ private void initData() { private void initEvent() { // set listener to change the current item of view pager when click bottom nav item bind.bnve.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + private int previousPosition = -1; + @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { // int id = 0; @@ -107,11 +110,20 @@ public boolean onNavigationItemSelected(@NonNull MenuItem item) { // id = 2; // break; // } -// bind.vp.setCurrentItem(id, false); +// if(previousPosition != id) { +// bind.vp.setCurrentItem(id, false); +// previousPosition = id; +// } // you can write as above. // I recommend this method. You can change the item order or counts without update code here. - bind.vp.setCurrentItem(fragmentMap.get(item.getItemId())); + int position = items.get(item.getItemId()); + if (previousPosition != position) { + // only set item when item changed + previousPosition = position; + Log.i(TAG, "-----bnve-------- previous item:" + bind.bnve.getCurrentItem() + " current item:" + position + " ------------------"); + bind.vp.setCurrentItem(position); + } return true; } }); @@ -125,12 +137,8 @@ public void onPageScrolled(int position, float positionOffset, int positionOffse @Override public void onPageSelected(int position) { - // check whether current item is equal position - if (bind.bnve.getCurrentItem() != position) { - // only set item when scroll view pager by hand - bind.bnve.setCurrentItem(position); - Log.i(TAG, "setCurrentItem:" + position); - } + Log.i(TAG, "-----ViewPager-------- previous item:" + bind.bnve.getCurrentItem() + " current item:" + position + " ------------------"); + bind.bnve.setCurrentItem(position); } @Override diff --git a/app/src/main/res/color/item_text_color.xml b/app/src/main/res/color/selector_item_color.xml similarity index 100% rename from app/src/main/res/color/item_text_color.xml rename to app/src/main/res/color/selector_item_color.xml diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index bfd1baa..ef319cd 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -25,6 +25,18 @@ android:layout_height="wrap_content" android:text="@string/with_view_pager" /> +