Android底部导航栏——bottomnavigation结合viewpager的实现

来源:互联网 发布:绝地求生画面优化教程 编辑:程序博客网 时间:2024/06/16 14:59

前言

在谷歌官方发布BottomNavigationView控件之前我们可以自己组合控件实现,比如LinearLayout + TextView(使用android:drawableTop属性+selector状态切换)、RadioGroup + RadioButton等等组合控件的方法自定义实现复杂效果。除了第三方外,现在我们多了一个选择,就是使用bottomnavigation结合viewpager的实现。后期会有文章介绍前面的几种实现方式,对比下来这种代码量最少,而且特别清晰。

一 使用LinearLayout + TextView实现了底部导航栏的效果


学习一种新的技术首先要看在gradle中的配置(菇凉能力有限这篇文章只讲解这个控件是怎么用的,感兴趣的小伙伴可以去看源代码):

1.1 build.gradle中

 compile'com.android.support:design:25.0.1' compile'com.android.support:support-v4:25.0.1'

1.2 xml文件中

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    xmlns:app="http://schemas.android.com/apk/res-auto"    tools:context="com.bottomnavigationview.MainActivity">    <android.support.v4.view.ViewPager        android:id="@+id/viewpager"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_above="@+id/bottom_navigation" />    <android.support.design.widget.BottomNavigationView        android:id="@+id/bottom_navigation"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        app:itemIconTint="@drawable/bottom_selector"        app:itemTextColor="@drawable/bottom_selector"        app:menu="@menu/bottom_menu" />    <View        android:layout_width="match_parent"        android:layout_height="5dp"        android:layout_above="@id/bottom_navigation"        android:background="@drawable/bottomshadow" /></RelativeLayout>

这里简单说一下android.support.design.widget.BottomNavigationView中的一些属性:

  1. app:itemIconTint=”@drawable/bottom_selector” :这个是底部栏图片颜色变化的selector

  2. app:itemTextColor=”@drawable/bottom_selector”:这个是底部栏文字颜色变化的selector

  3. app:menu=”@menu/bottom_menu”:这个是底部栏模块item的定义,包括文字和图片



1.3 在res下新建menu文件夹,新建一个menu菜单 ,代码如下:

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android">    <item        android:id="@+id/item_news"        android:icon="@mipmap/icon_navigation_home_01"        android:title="首页" />    <item        android:id="@+id/item_lib"        android:icon="@mipmap/icon_navigation_shop_01"        android:title="搜索" />    <item        android:id="@+id/item_find"        android:icon="@mipmap/icon_navigation_ucenter_01"        android:title="我的" />    <item        android:id="@+id/item_more"        android:icon="@mipmap/icon_navigation_home_01"        android:title="主页" /></menu>


1.4 在drawable下新建.xml文件 颜色和文字变化的颜色一样selector,代码如下

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:color="@color/p_select_color"         android:state_checked="true" />    <item android:color="@color/p_99_color" android:state_checked="false" /></selector>


1.5 MainActivity中的主要代码:

package com.bottomnavigationview;import android.os.Bundle;import android.support.annotation.NonNull;import android.support.design.widget.BottomNavigationView;import android.support.v4.view.ViewPager;import android.support.v7.app.AppCompatActivity;import android.view.MenuItem;public class MainActivity extends AppCompatActivity {    private ViewPager viewPager;    private MenuItem menuItem;    private BottomNavigationView bottomNavigationView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        viewPager = (ViewPager) findViewById(R.id.viewpager);        bottomNavigationView = (BottomNavigationView)findViewById(R.id.bottom_navigation);        //默认 >3 的选中效果会影响ViewPager的滑动切换时的效果,故利用反射去掉 BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);        bottomNavigationView.setOnNavigationItemSelectedListener(                new BottomNavigationView.OnNavigationItemSelectedListener() {                    @Override                    public boolean onNavigationItemSelected(@NonNull MenuItem item) {                        switch (item.getItemId()) {                            case R.id.item_news:                                viewPager.setCurrentItem(0);                                break;                            case R.id.item_lib:                                viewPager.setCurrentItem(1);                                break;                            case R.id.item_find:                                viewPager.setCurrentItem(2);                                break;                            case R.id.item_more:                                viewPager.setCurrentItem(3);                                break;                        }                        return false;                    }                });        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {            @Override            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {            }            @Override            public void onPageSelected(int position) {                if (menuItem != null) {                    menuItem.setChecked(false);                } else {                    bottomNavigationView.getMenu().getItem(0).setChecked(false);                }                menuItem = bottomNavigationView.getMenu().getItem(position);                menuItem.setChecked(true);            }            @Override            public void onPageScrollStateChanged(int state) {            }        });        //禁止ViewPager滑动//        viewPager.setOnTouchListener(new View.OnTouchListener() {//            @Override//            public boolean onTouch(View v, MotionEvent event) {//                return true;//            }//        });        setupViewPager(viewPager);    }    private void setupViewPager(ViewPager viewPager) {        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());        adapter.addFragment(BaseFragment.newInstance("首页"));        adapter.addFragment(BaseFragment.newInstance("搜索"));        adapter.addFragment(BaseFragment.newInstance("我的"));        adapter.addFragment(BaseFragment.newInstance("主页"));        viewPager.setAdapter(adapter);    }}

注意点:

官方的BottomNavigationView用起来虽然简单,但是有一个很坑的问题,就是它内部在item>4的时候出现动画的效果。如下:

这里写图片描述

在平时的开发中这种效果也是特别崩溃的,因为官方没有默认的方法取消这种效果,这时候需要我们用到反射。

创建一个Helper类

package com.bottomnavigationview;import android.annotation.TargetApi;import android.os.Build;import android.support.design.internal.BottomNavigationItemView;import android.support.design.internal.BottomNavigationMenuView;import android.support.design.widget.BottomNavigationView;import java.lang.reflect.Field;/** * Created by 凉菇凉 on 2017/8/2. */public class BottomNavigationViewHelper {    @TargetApi(Build.VERSION_CODES.KITKAT)    public static void disableShiftMode(BottomNavigationView navigationView) {        BottomNavigationMenuView menuView = (BottomNavigationMenuView) navigationView.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 itemView = (BottomNavigationItemView) menuView.getChildAt(i);                itemView.setShiftingMode(false);                itemView.setChecked(itemView.getItemData().isChecked());            }        } catch (NoSuchFieldException | IllegalAccessException e) {            e.printStackTrace();        }    }}

使用的时候

 BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);

1.6 其实避了这个坑是特别简单的,viewpager就不在这里详细说了。来上一张效果动图。

这里写图片描述

阅读全文
0 0