相比之前實現導航欄的方式,如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定義如下:
<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
封裝了好多東西 裏面包含有角標 ,可以實現消息提示
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