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

前沿   距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"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">


<item
    android:id="@+id/home"
    android:icon="@drawable/ic_home_white_24dp"
    android:title="首頁" />


    <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" />


</menu>

MainActivity XML定義如下:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"


    tools:context="com.createfuture.android.md50.MainActivity">


    <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"
        />


</LinearLayout>




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 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<V> ,重寫必要的方法實現

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


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