前沿 距Google I/O(2014)最新发布的 Material Design Android 设计风格已经有一段时间了, 2016年Google在 Android Design Support Library 25基础上增加了 一个BottomNavigationView 新控件,相比之前实现导航栏的方式,如LinearLayout + TextView(使用android:drawableTop属性+selector状态切换)、LinearLayout + RelativeLayout(TextView+ImageView)
RadioGroup + RadioButton,2015年Google推出的兼容包Android Design Support Library中的TabLayout等,该控件提供更简洁的方式实现功能模块导航,符合材料设计规范,效果图如下:
BottomNavigationView 继承自 FrameLayout,
对外暴露了OnNavigationItemSelectedListener接口,便于对子视图点击事件的处理,可以通过此接口动态改变文字颜色 和图标颜色。
在XML中需要了解其以下属性
(记得添加 xmlns:app=“http://schemas.android.com/apk/res-auto”)
app:itemIconTint : 设置图标着色
app:itemTextColor : 设置文本颜色
app:menu : 设置菜单
app:itemBackground : 设置导航栏的背景色
默认该控件图标、文本都使用系统自带的@color/colorPrimary颜色 需要注意的是源码中明确指出最大子View个数不能超过5个,在子View个数大于等于4的时候 只有选中的显示文字,没有选中的只显示图标,并且会显示自带的动画,貌似看起来有些浮夸。
在源码BottomNavigationMenuView中,有一个全局变量:mShiftingMode, private boolean mShiftingMode = true;在创建、更新Menu的时候调用了buildMenuView()方法
public void buildMenuView() {
mShiftingMode = mMenu.size() > 3;
}
具体效果图如下:
下面使用BottomNavigationView+ViewPager+Fragment组合实现 导航展示界面 真机5.0.2测试
使用前打开build.gradle 添加依赖
//可以修改为你项目中对应的版本号 建议修改与 compile ‘com.android.support:appcompat-v7:25.0.0’ 相同的版本号
compile ‘com.android.support:design:25.0.0’
首先在Res目录下创建一个menu文件夹,并新建一个activity_main_bottom.xml
<?xml version="1.0" encoding="utf-8"?><item
android:id="@+id/love"
android:icon="@drawable/ic_favorite_white_24dp"
android:title="喜欢" />
<item
android:id="@+id/video"
android:icon="@drawable/ic_videogame_asset_white_24dp"
android:title="视频" />
<item
android:id="@+id/book"
android:icon="@drawable/ic_book_white_24dp"
android:title="订阅" />
<item
android:id="@+id/github"
android:icon="@drawable/ic_github_circle_white_24dp"
android:title="Github" />
MainActivity XML定义如下:
<?xml version="1.0" encoding="utf-8"?><android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.9" />
<android.support.design.widget.BottomNavigationView
android:id="@+id/main_bottom_nav_bar"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.1"
android:background="@android:color/white"
app:itemIconTint="#be4c00"
app:itemTextColor="#be4c00"
app:menu="@menu/activity_main_bottom"
/>
BaseActivity基类简单封装如下:
public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutViewId());
//initView
initView();
//initData
initData();
//initListener
initListener();
}
protected abstract void initListener();
protected abstract void initData();
protected abstract void initView();
// UI View Layout
protected abstract @LayoutRes int getLayoutViewId();
//get View ID
public <T extends View> T getViewId(int id){
View view=getWindow().getDecorView().findViewById(id);
return (T) view;
}
}
MainActivity代码如下:
package com.createfuture.android.guidenavigationbar;
import android.annotation.SuppressLint;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.design.internal.BottomNavigationItemView;
import android.support.design.internal.BottomNavigationMenuView;
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.v4.view.ViewPager;
import android.util.Log;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
import com.createfuture.android.md50.R;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends BaseActivity implements BottomNavigationView.OnNavigationItemSelectedListener,
ViewPager.OnPageChangeListener {
private ViewPager viewPager;//实现左右滑动的ViewPager
private ViewPager viewPager;//实现左右滑动的ViewPager
private BottomNavigationView bottomNavigationView;//底部导航栏
private List<Fragment> myFragment = new ArrayList<>();//存放Fragment集合
private String[] mTiltls = new String[]{"首页", "喜欢", "视频", "订阅", "Github"};
private long currentTime = 0;
@Override
protected int getLayoutViewId()
{
return R.layout.activity_main;
}
@Override
protected void initView() {
bottomNavigationView = getViewId(R.id.main_bottom_nav_bar);
//设置背景色
bottomNavigationView.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#ffffbb33"))); //禁用模式
disableShiftMode(bottomNavigationView);
//设置默认选中最后一个
bottomNavigationView.setSelectedItemId(R.id.github);
viewPager = getViewId(R.id.viewPager);
//可以设置ViewPager禁止滑动
//禁止ViewPager滑动
viewPager.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
}
/**
*
* 如何禁用ShiftingMode这种模式,stackoverflow上面找到解决办法:反射:
* <a href="https://stackoverflow.com/questions/40176244/how-to-disable-bottomnavigationview-shift-mode">禁用</a>.
*/
@SuppressLint("RestrictedApi")
public void disableShiftMode(BottomNavigationView view) {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
try {
Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
shiftingMode.setAccessible(true);
shiftingMode.setBoolean(menuView, false);
shiftingMode.setAccessible(false);
for (int i = 0; i < menuView.getChildCount(); i++) {
BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
//noinspection RestrictedApi
item.setShiftingMode(false);
// set once again checked value, so view will be updated
//noinspection RestrictedApi
item.setChecked(item.getItemData().isChecked());
}
} catch (NoSuchFieldException e) {
Log.e("shiftingMode", "Unable to get shift mode field", e);
} catch (IllegalAccessException e) {
Log.e("shiftingMode", "Unable to change value of shift mode", e);
}
}
/**
* 初始化底部导航栏数据 Fragment集合 并配置适配器
*/
@Override
protected void initData() {
for (int i = 0; i < mTiltls.length; i++) {
myFragment.add(TestFragment.getInstance(mTiltls[i]));
}
viewPager.setAdapter(new CustomPagerAdapter(getSupportFragmentManager()));
viewPager.setCurrentItem(4);
}
@Override
protected void initListener() {
bottomNavigationView.setOnNavigationItemSelectedListener(this);
viewPager.setOnPageChangeListener(this);
}
/**
* @param item 获取到MenuItem Id
* @return 返回true 显示选中效果 反之不会显示
*/
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
//
int itemId = item.getItemId();
switch (itemId) {
case R.id.home:
viewPager.setCurrentItem(0);
break;
case R.id.love:
viewPager.setCurrentItem(1);
break;
case R.id.video:
viewPager.setCurrentItem(2);
break;
case R.id.book:
viewPager.setCurrentItem(3);
break;
case R.id.github:
viewPager.setCurrentItem(4);
break;
}
return true;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
/**
* 选中的效果
* //API 21 及其以上才可以设置setBackgroundTintList
* @param position
*/
@SuppressLint("ResourceAsColor")
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onPageSelected(int position) {
switch (position) {
case 0:
bottomNavigationView.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#ffff8800")));
bottomNavigationView.setSelectedItemId(R.id.home);
break;
case 1:
bottomNavigationView.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#ff99cc00")));
bottomNavigationView.setSelectedItemId(R.id.love);
break;
case 2:
bottomNavigationView.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#ff0099cc")));
bottomNavigationView.setSelectedItemId(R.id.video);
break;
case 3:
bottomNavigationView.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY));
bottomNavigationView.setSelectedItemId(R.id.book);
break;
case 4:
bottomNavigationView.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#ffffbb33")));
bottomNavigationView.setSelectedItemId(R.id.github);
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
//ViewPager Adapter 真正开发 记得要新建一个类,尽可能的少用内部类
private class CustomPagerAdapter extends FragmentPagerAdapter {
public CustomPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return myFragment == null ? null : myFragment.get(position);
}
@Override
public int getCount() {
return myFragment.size() == 0 ? 0 : myFragment.size();
}
}
/**
* 监听返回键
*/
@Override
public void onBackPressed() {
if (viewPager.getCurrentItem() != 0) {
viewPager.setCurrentItem(0);
} else {
exit();
}
}
//退出
private void exit() {
if (System.currentTimeMillis() -currentTime >2000) {
currentTime = System.currentTimeMillis();
Toast.makeText(this, "再按一次退出", Toast.LENGTH_SHORT).show();
} else {
finish();
}
}
}
TestFragment代码如下:
package com.createfuture.android.guidenavigationbar;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* Created by GuoBin on 2017/12/23.
*/
public class TestFragment extends Fragment {
//静态常量标识
private final static String KEY=TestFragment.class.getSimpleName();
public static Fragment getInstance(String textContent){
/**
* 实例化当前Fragment 并初始化Bundle 保存数据到Fragment,用于Fragment界面文本展示
*/
TestFragment fragment=new TestFragment();
Bundle bundle=new Bundle();
bundle.putString(KEY,textContent);
fragment.setArguments(bundle);
return fragment;
}
/**
* 加载视图
* @param inflater
* @param container
* @param savedInstanceState
* @return
*/
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
/**
* 布局文件通过动态生成 首先新建一个 RelativeLayout,设置宽高属性
* 同理新建一个TextView,设置宽高属性,并设置文本
* 将TextView添加到RelativeLayout中
*/
RelativeLayout relativeLayout=new RelativeLayout(getContext().getApplicationContext());
RelativeLayout.LayoutParams layoutParams=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
relativeLayout.setLayoutParams(layoutParams);
TextView textView=new TextView(getContext().getApplicationContext());
textView.setLayoutParams(layoutParams);
textView.setGravity(Gravity.CENTER);
textView.setTextSize(23);
textView.setTextColor(Color.BLACK);
textView.setText(getArguments().getString(KEY)!=null?getArguments().getString(KEY).toString():"");
relativeLayout.addView(textView);
return relativeLayout;
}
}
官方的BottomNavigationView的item个数大于4个的时候会自动的改变显示模式,
隐藏了文字,相比之下,下面的导航栏就没有这个问题,而且功能更全。
目前github开源了几个好用的控件,
第一个:外国开源 https://github.com/aurelhubert/ahbottomnavigation
下面是包含的开源文件
AHNotification.java
AHNotificationHelper.java
AHBottomNavigation.java
AHBottomNavigationAdapter.java
AHBottomNavigationBehavior.java
AHBottomNavigationFABBehavior.java
AHBottomNavigationItem.java
AHBottomNavigationViewPager.java
AHHelper.java
VerticalScrollingBehavior.java
.
可以实现消息角标提示等效果,如图:
第二个:外国开源https://github.com/Ashok-Varma/BottomNavigation
封装了好多东西 里面包含有角标 ,可以实现消息提示
behaviour文件包含
BottomNavBarFabBehaviour.java
BottomVerticalScrollBehavior.java
VerticalScrollingBehavior.java
utils文件夹中包含如下:
BadgeItem.java
BottomNavigationBar.java
BottomNavigationHelper.java
BottomNavigationItem.java
BottomNavigationTab.java
FixedBottomNavigationTab.java
ShapeBadgeItem.java2.0.1 released
ShiftingBottomNavigationTab.java
TextBadgeItem.java
效果图:
第三个:外国开源
https://github.com/armcha/LuseenBottomNavigation
实现效果跟官方的类似,这里就不贴图了
包含文件:
BottomNavigationItem.java
BottomNavigationUtils.java
BottomNavigationView.java
OnBottomNavigationItemClickListener.java
主要说一下第一个开源实现案例 自定义ViewPager+底部导航栏AHBottomNavigation+自定义Fragment实现
首先引入依赖
compile 'com.aurelhubert:ahbottomnavigation:2.1.0'
compile 'com.android.support:design:25+'
注意:如果想实现如图所示的效果,需要在页面中添加一个上下滑动的列表,如果不是RecyclerView,没有上下联动效果,如果想自己实现,可以继承CoordinatorLayout.Behavior ,重写必要的方法实现
RecyclerView对应的适配器 MyAdapter代码如下:
package com.createfuture.android.aurelhubertahbottomnavigation;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
/**
* RecyclerView列表适配器
*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
//集合
private ArrayList<String> mDataset = new ArrayList<>();
//数据入口
public MyAdapter(ArrayList<String> dataset) {
mDataset.clear();
mDataset.addAll(dataset);
}
/**
* 创建视图
*
* @param parent
* @param viewType
* @return
*/
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_item_demo, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
/**
* 绑定数据到 TextView
*
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mTextView.setText(mDataset.get(position));
}
/**
* 获取集合大小
*
* @return
*/
@Override
public int getItemCount() {
return mDataset.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public ViewHolder(View v) {
super(v);
mTextView = (TextView) v.findViewById(R.id.layout_item_demo_title);
}
}
}
列表子视图layout_item_demo.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical"
android:layout_margin="8dp">
<TextView
android:id="@+id/layout_item_demo_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:padding="16dp"
android:textColor="#212121"
android:textSize="18sp" />
</RelativeLayout>
自定义一个Fragment 起名为TestFragment 对应布局文件(fragment_demo_list.xml)如下:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/fragment_container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/fragment_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
TestFragment文件内容:
package com.createfuture.android.aurelhubertahbottomnavigation;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
/**
* Created by GuoBin on 2017/12/23.
*/
public class TestFragment extends Fragment {
//RecyclerView
private RecyclerView recyclerView;
//RecyclerView.LayoutManager
private RecyclerView.LayoutManager layoutManager;
//静态常量标识
private final static String KEY = TestFragment.class.getSimpleName();
//列表适配器
private MyAdapter mAdapter;
/**
* 获得带有数据的TestFragment实类
* @param content
* @return
*/
public static Fragment getInstance(String content) {
/**
* 实例化当前Fragment 并初始化Bundle 保存数据到Fragment,用于Fragment界面文本展示
*/
TestFragment fragment = new TestFragment();
Bundle bundle = new Bundle();
bundle.putString(KEY, content);
fragment.setArguments(bundle);
return fragment;
}
//加载布局
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_demo_list, container, false);
initDemoList(view);
return view;
}
private void initDemoList(View view) {
recyclerView = (RecyclerView) view.findViewById(R.id.fragment_recycler_view);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
//初始化数据
ArrayList<String> itemsData = new ArrayList<>();
for (int i = 0; i < 50; i++) {
itemsData.add("Fragment " + getArguments().get(KEY));
}
mAdapter = new MyAdapter(itemsData);
recyclerView.setAdapter(mAdapter);
}
}
MainActivity对应的布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.aurelhubert.ahbottomnavigation.AHBottomNavigationViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/floating_action_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_marginBottom="88dp"
android:src="@mipmap/ic_content_add"
app:useCompatPadding="true"/>
<com.aurelhubert.ahbottomnavigation.AHBottomNavigation
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:selectedBackgroundVisible="false"/>
</android.support.design.widget.CoordinatorLayout>
MainActivity对应的代码如下:
package com.createfuture.android.aurelhubertahbottomnavigation;
import android.animation.Animator;
import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.animation.LinearOutSlowInInterpolator;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.OvershootInterpolator;
import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem;
import com.aurelhubert.ahbottomnavigation.AHBottomNavigationViewPager;
import com.aurelhubert.ahbottomnavigation.notification.AHNotification;
import java.util.ArrayList;
import java.util.List;
/**
* CoordinatorLayout+底部导航栏+自定义A HBottomNavigationViewPager+Fragment
* 实现如图效果
*/
public class MainActivity extends AppCompatActivity implements AHBottomNavigation.OnTabSelectedListener{
//UI元素
private AHBottomNavigationViewPager viewPager;//自定义ViewPager
private AHBottomNavigation bottomNavigation;//底部导航栏
private FloatingActionButton floatingActionButton;//悬浮按钮
//Fragment集合
private List<Fragment> myFragment=new ArrayList<>();
//底部导航栏标题
private String[] mTiltls = new String[]{"Menu1", "Menu2", "Menu3", "Menu4", "Menu5"};
//底部导航栏子项集合
private ArrayList<AHBottomNavigationItem> bottomNavigationItems = new ArrayList<>();
//消息通知
private AHNotification notification;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
initListener();
}
//初始化控件
private void initView() {
bottomNavigation = (AHBottomNavigation) findViewById(R.id.bottom_navigation);
//选中的图标着色以及文本的颜色
bottomNavigation.setAccentColor(Color.RED);
//没有选中的图标着色以及文本的颜色
bottomNavigation.setInactiveColor(Color.BLACK);
//去除隐藏标题的状态
bottomNavigation.setTitleState(AHBottomNavigation.TitleState.ALWAYS_SHOW);
viewPager = (AHBottomNavigationViewPager) findViewById(R.id.view_pager);
viewPager.setPagingEnabled(false);//禁止滑动
floatingActionButton = (FloatingActionButton) findViewById(R.id.floating_action_button);
//管理Floating的显示行为
bottomNavigation.manageFloatingActionButtonBehavior(floatingActionButton);
//交互行为可用
// bottomNavigation.setBehaviorTranslationEnabled(true);
}
//初始化数据
private void initData() {
/**
* 为导航栏添加带图标的文字
*/
AHBottomNavigationItem item1 = new AHBottomNavigationItem(mTiltls[0], R.mipmap.ic_maps_place, Color.YELLOW);
AHBottomNavigationItem item2 = new AHBottomNavigationItem(mTiltls[1], R.mipmap.ic_maps_local_bar, Color.YELLOW);
AHBottomNavigationItem item3 = new AHBottomNavigationItem(mTiltls[2], R.mipmap.ic_maps_local_restaurant, Color.YELLOW);
AHBottomNavigationItem item4 = new AHBottomNavigationItem(mTiltls[3], R.mipmap.ic_book_white_24dp, Color.YELLOW);
AHBottomNavigationItem item5 = new AHBottomNavigationItem(mTiltls[4], R.mipmap.ic_github_circle_white_24dp, Color.YELLOW);
bottomNavigationItems.add(item1);
bottomNavigationItems.add(item2);
bottomNavigationItems.add(item3);
bottomNavigationItems.add(item4);
bottomNavigationItems.add(item5);
bottomNavigation.addItems(bottomNavigationItems);
//初始化消息提示
notification=new AHNotification.Builder()
.setText("3")
.setTextColor(Color.WHITE)
.setBackgroundColor(Color.RED)
.build();
//为最后一个加消息提示
bottomNavigation.setNotification(notification,4);
//添加Viewpager中Fragment集合
for (int i = 0; i < mTiltls.length; i++) {
if (i != 4) {
myFragment.add(TestFragment.getInstance(mTiltls[i].toString()));
}else {
myFragment.add(TestFragment.getInstance(""));
}
}
//ViewPager绑定适配器
viewPager.setAdapter(new CustomPagerAdapter(getSupportFragmentManager()));
}
//初始化监听
private void initListener() {
bottomNavigation.setOnTabSelectedListener(this);
}
/**
* tab 选中的效果
* @param position int: Position of the selected tab
* @param wasSelected boolean: true if the tab was already selected
* @return
*/
@Override
public boolean onTabSelected(int position, boolean wasSelected) {
viewPager.setCurrentItem(position, false);
if (position == 1) {
bottomNavigation.setNotification("1", 1);
floatingActionButton.setVisibility(View.VISIBLE);
floatingActionButton.setAlpha(0f);
floatingActionButton.setScaleX(0f);
floatingActionButton.setScaleY(0f);
floatingActionButton.animate()
.alpha(1)
.scaleX(1)
.scaleY(1)
.setDuration(300)
.setInterpolator(new OvershootInterpolator())
.setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
floatingActionButton.animate()
.setInterpolator(new LinearOutSlowInInterpolator())
.start();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
})
.start();
} else {
if (floatingActionButton.getVisibility() == View.VISIBLE) {
floatingActionButton.animate()
.alpha(0)
.scaleX(0)
.scaleY(0)
.setDuration(300)
.setInterpolator(new LinearOutSlowInInterpolator())
.setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
floatingActionButton.setVisibility(View.GONE);
}
@Override
public void onAnimationCancel(Animator animation) {
floatingActionButton.setVisibility(View.GONE);
}
@Override
public void onAnimationRepeat(Animator animation) {
}
})
.start();
}
}
return true;
}
//ViewPager Adapter 真正开发 记得要新建一个类,尽可能的少用内部类
private class CustomPagerAdapter extends FragmentPagerAdapter {
public CustomPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return myFragment == null ? null : myFragment.get(position);
}
@Override
public int getCount() {
return myFragment.size() == 0 ? 0 : myFragment.size();
}
}
}
代码注释已经很清楚了,不做太多重复解释。
除了上面显示的底部导航栏效果,还有一种也是较为常见的,先上图:
感兴趣可以到Github,传送门:https://github.com/armcha/Space-Navigation-View