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
中的一些属性:
app:itemIconTint=”@drawable/bottom_selector” :这个是底部栏图片颜色变化的selector
app:itemTextColor=”@drawable/bottom_selector”:这个是底部栏文字颜色变化的selector
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就不在这里详细说了。来上一张效果动图。
- Android底部导航栏——bottomnavigation结合viewpager的实现
- 底部导航栏:利用viewpager实现Android底部标题栏
- 底部导航栏:利用viewpager实现Android底部标题栏
- Android——ViewPager和底部导航的配合
- Android底部导航栏——FragmentTabHost+ViewPager+Fragment
- 实例—ViewPager+RadioGroup实现底部导航栏和页面的滑动
- Android——BottomNavigationBar底部导航栏的快速实现
- ANDROID底部导航栏的实现(一)— BottomNavigationBar
- 底部导航栏(自定义View+ViewPager实现) android项目详解
- Android底部导航栏实现(四)之TabLayout+ViewPager
- Android 用 TabLayout + ViewPager + Fragment 实现顶部、底部导航栏
- 【Android】Fragment+Viewpager实现底部导航栏(带小红点)
- FragmentTabHost+ViewPager实现滑动的底部导航栏
- Radio+不可滑动的viewpager实现底部导航栏
- Android之RadioGroup+ViewPager制作的底部导航栏
- Android之RadioGroup+ViewPager制作的底部导航栏
- Android之RadioGroup+ViewPager制作的底部导航栏
- FragmentTabHost+viewPager实现底部导航栏
- 单片机开发之按键
- Binder机制总结起来就这一段话
- 快速搭建maven+Spring-boot框架(附代码)
- 15、oracle:计算两个时间的差值
- 对XML文件的重新认识,说说XML文件的二三事(二):两种验证模式-DTD和XSD
- Android底部导航栏——bottomnavigation结合viewpager的实现
- 动态规划(一)
- AJAX实现跨域请求
- LED样式的jQuery时间倒计时插件
- 《深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)周志明 著》阅读笔记目录(已完结)
- shell笔记
- HTML5_转译字符、相对路径、绝对路径、根相对路径
- Android NDK开发之旅(2):一篇文章搞定Android Studio中使用CMake进行NDK/JNI开发
- Windows2012服务器上安装Apache+php+mysql