Android 最常用的四种底部导航栏实现

Posted Mq_sir

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 最常用的四种底部导航栏实现相关的知识,希望对你有一定的参考价值。

android 底部导航栏实现

底部导航栏的应用非常的广泛。今天就总结下几种实现的方式。

一、Fragment + TextView 实现

前面一篇博客在介绍Fragment 的时候就使用了Fragment + ImageView 实现了一个底部导航栏点击的例子,只要把ImageView 替换为TextView 是一样的实现。这里就详细介绍了,可以看这篇博客Android之Fragment的概述和使用

这种方式每次点击我们都要重置 所有TextView的状态,然后选中点击的TextView

二、RadioGroup + ViewPager 实现

我们只需重写RadioGroup的onCheckedChange,判断checkid即可知道点击的是哪个RadioButton,再给ViewPager 设置监听,让底部导航栏和viewpager同步就行了。

运行效果:

在这里插入图片描述

  1. 新建四个布局文件

在这里插入图片描述
这里我放一个布局文件的代码,其他几个都是一样的。

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

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="500dp"
        android:src="@drawable/tx4"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我的"
        android:textSize="50sp"
        android:textColor="#ff0000"
        android:layout_gravity="center" />

</LinearLayout>
  1. 编写我们更换底部导航栏图标的xml,和导入我们的图标,选中和没有选中个一个不同的颜色。这里就给出一个me_drawable.xml的例子

在这里插入图片描述
分别设置选中和没有选中的图片

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:drawable="@drawable/me_select"/>
    <item android:state_checked="false" android:drawable="@drawable/me_normal"/>
</selector>
  1. 编写activity_main.xml布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context="com.mq.bottomtoobar2.MainActivity">

<androidx.viewpager.widget.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/rg_tab"/>

    <RadioGroup
        android:id="@+id/rg_tab"
        android:layout_width="fill_parent"
        android:layout_height="55dp"
        android:gravity="center_vertical"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/rb_msg"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:checked="true"
            android:drawableTop="@drawable/msg_drawable"
            android:gravity="center"
            android:paddingLeft="0dp"
            android:text="信息" />
        <RadioButton
            android:id="@+id/rb_people"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:drawableTop="@drawable/people_drawable"
            android:gravity="center"
            android:paddingLeft="0dp"
            android:text="联系人" />

        <RadioButton
            android:id="@+id/rb_find"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:drawableTop="@drawable/find_drawable"
            android:gravity="center"
            android:paddingLeft="0dp"
            android:text="发现" />
        <RadioButton
            android:id="@+id/rb_me"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:drawableTop="@drawable/me_drawable"
            android:gravity="center"
            android:paddingLeft="0dp"
            android:text="" />
    </RadioGroup>
</RelativeLayout>

注意: android:button="@null" 属性可以将边上的圈圈去掉。

  1. 编写MainActivity代码
public class MainActivity extends AppCompatActivity {

    private ViewPager mViewPager;
    private RadioGroup mRadioGroup;
    private RadioButton tab1,tab2,tab3,tab4;  //四个单选按钮
    private List<View> mViews;   //存放视图
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();//初始化数据
        //对单选按钮进行监听,选中、未选中
        mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                switch (i) {
                    case R.id.rb_msg:
                        mViewPager.setCurrentItem(0);
                        break;
                    case R.id.rb_people:
                        mViewPager.setCurrentItem(1);
                        break;
                    case R.id.rb_find:
                        mViewPager.setCurrentItem(2);
                        break;
                    case R.id.rb_me:
                        mViewPager.setCurrentItem(3);
                        break;
                }
            }
        });

    }
    
    private void initView() {
        //初始化控件
        mViewPager=findViewById(R.id.viewpager);
        mRadioGroup=findViewById(R.id.rg_tab);
        tab1=findViewById(R.id.rb_msg);
        tab2=findViewById(R.id.rb_people);
        tab3=findViewById(R.id.rb_find);
        tab4=findViewById(R.id.rb_me);

        mViews=new ArrayList<View>();//加载,添加视图
        mViews.add(LayoutInflater.from(this).inflate(R.layout.msg,null));
        mViews.add(LayoutInflater.from(this).inflate(R.layout.people,null));
        mViews.add(LayoutInflater.from(this).inflate(R.layout.find,null));
        mViews.add(LayoutInflater.from(this).inflate(R.layout.me,null));

        mViewPager.setAdapter(new MyViewPagerAdapter());//设置一个适配器
        //对viewpager监听,让分页和底部图标保持一起滑动
        mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override   //让viewpager滑动的时候,下面的图标跟着变动
            public void onPageSelected(int position) {
                switch (position) {
                    case 0:
                        tab1.setChecked(true);
                        tab2.setChecked(false);
                        tab3.setChecked(false);
                        tab4.setChecked(false);
                        break;
                    case 1:
                        tab1.setChecked(false);
                        tab2.setChecked(true);
                        tab3.setChecked(false);
                        tab4.setChecked(false);
                        break;
                    case 2:
                        tab1.setChecked(false);
                        tab2.setChecked(false);
                        tab3.setChecked(true);
                        tab4.setChecked(false);
                        break;
                    case 3:
                        tab1.setChecked(false);
                        tab2.setChecked(false);
                        tab3.setChecked(false);
                        tab4.setChecked(true);
                        break;
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    //ViewPager适配器
    private class MyViewPagerAdapter extends PagerAdapter {
        @Override
        public int getCount() {
            return mViews.size();
        }


        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
            return view==object;
        }

        @Override
        public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
            container.removeView(mViews.get(position));
        }

        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, int position) {
            container.addView(mViews.get(position));
            return mViews.get(position);
        }
    }
}

三、BottomNavigationView+ViewPager+fragment 实现

这是 Google 给我们提供的一个专门用于底部导航的 View,你只需要在新建 Activity 的时候选择 “Bottom Navigation Activity”就可以了。

在这里插入图片描述
运行效果:

在这里插入图片描述
BottomNavigationView 的Tab是通过menu 的方式添加的。使用较为简单,不需要你自己定义控件,只需要自己修改他给你定义的menu文件和回调方法
这里不过多的介绍了,大家可以去看一下里面的代码。
在这里插入图片描述

四、TabLayout+fragment+viewPager 实现

实现底部导航栏我们很容易想到使用表格布局,下面就是一个个的tab切换viewpager就行。

这种实现方最为常用吧。

运行效果:
在这里插入图片描述

  1. 在build.gradle导入工具包:
    implementation 'com.android.support:design:27.1.1'
    implementation 'com.android.support:support-v4:27.1.1'
  1. 编写 activity2_main.xml 布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:app="http://schemas.android.com/apk/res-auto">

<androidx.viewpager.widget.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/tablayout"/>
<com.google.android.material.tabs.TabLayout
    android:id="@+id/tablayout"
    android:layout_alignParentBottom="true"
    android:layout_width="match_parent"
    android:layout_height="50dp">
</com.google.android.material.tabs.TabLayout>
</RelativeLayout>
  1. 编写四个Fragment以及布局

在这里插入图片描述
这里给出一个Fragment,其余几个都是一样的。

public class me extends Fragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_me, container, false);
    }
}

布局代码

<FrameLayout 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"
    tools:context="com.mq.bottomtoobar3.me">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/tx4"/>

</FrameLayout>
  1. 编写MyAdapt继承FragmentPagerAdapter的适配器
public class MyAdapt extends FragmentPagerAdapter {

    private List<Fragment> mFragments;
    private List<String> mtitle;

    public

以上是关于Android 最常用的四种底部导航栏实现的主要内容,如果未能解决你的问题,请参考以下文章

带有片段和底部导航栏的 Android FloatingActionButton

底部导航片段应用程序不断崩溃

在android中使用底部导航的最佳实践:活动与片段

Android Jetpack导航,另一个主机片段内的主机片段

android布局 底部导航栏布局问题

如何为导航到实现底部导航栏的活动中的上一个片段进行后推操作?