BottomNavigationVie 底部導航欄實現方式多樣化 Material Design

在這裏插入圖片描述
前沿 距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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章