前沿 距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