Android---简易的底部导航栏

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

目录

一、activity_main.xml布局

二、给ViewPager2 创建适配器

三、ViewPager2 数据源

四、MainActivity.java类

 1、初始化数据源。

2、ViewPager2 页面改变监听

3、BottomNavigationView 的每个 item 点击的监听

 这里简单演示实现效果实现快速开发并没有太好的UI界面。当掌握好了知识点再来优化界面。实现上面的效果主要用到 ViewPager2 + Fragment + BottomNavigationView

一、activity_main.xml布局

        这里只有两个控件。第一个 ViewPager2用来放 Fragment。第二个是 BottomNavigationView 实现底部导航。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    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=".MainActivity">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/main_viewPager"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="0dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="0dp"
        android:layout_marginBottom="19dp"
        app:layout_constraintBottom_toTopOf="@+id/main_bottomNavigationView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/main_bottomNavigationView"
        android:layout_width="0dp"
        android:layout_height="78dp"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="5dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/main_viewPager"
        app:menu="@menu/bottomnavigationitem"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

        给底部导航增加菜单按钮。在 BottomNavigationView 里添加属性 app:menu="@menu/bottomnavigationitem"。在 res 目录下 New --> Directory 新建一个menu目录。在menu目录上 New --> Menu Source File 新建一个 bottomnavigationitem.xml 文件。

        在bottomnavigationitem.xml 里添加一个 item 就是在 底部导航栏里添加了一个可点击的 tab 按钮。注意item 里面的 icon 属性你可以自己找一下好看的icon这里简单用 mipmap 里的 ic_launcher.webp 来作为 icon。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/fragment_1"
        android:icon="@mipmap/ic_launcher"
        android:title="T1"/>
    <item
        android:id="@+id/fragment_2"
        android:icon="@mipmap/ic_launcher"
        android:title="T2"/>
    <item
        android:id="@+id/fragment_3"
        android:icon="@mipmap/ic_launcher"
        android:title="T3"/>
    <item
        android:id="@+id/fragment_4"
        android:icon="@mipmap/ic_launcher"
        android:title="T4"/>
    <item
        android:id="@+id/fragment_5"
        android:icon="@mipmap/ic_launcher"
        android:title="T5"/>

</menu>

二、给ViewPager2 创建适配器

        ViewPager2 是高级 UI。通过适配器 Adapter 来适配数据源。创建一个 MyFragmentStateAdapter.class 类继承 FragmentStateAdapter实现两个方法 createFragment() 和 getItemCount()。

        注意

        1、ViewPager 是与 FragmentPagerAdapter 搭配的。而 FragmentPagerAdapter 继承自 PagerAdapter。而 FragmentPagerAdapter 已经被官方给废弃了。

        2、ViewPager2 是与 FragmentStateAdapter 搭配的。而 FragmentStateAdapter 继承自 RecyclerView.Adapter。因此可以用到 RecyclerView 的性质比如垂直滑动效果。

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;

import java.util.List;

public class MyFragmentStateAdapter extends FragmentStateAdapter {

    private List<Fragment> mData;

    public MyFragmentStateAdapter(FragmentActivity fragmentActivity, List<Fragment> mData) {
        super(fragmentActivity);
        this.mData = mData;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return mData.get(position);
    }

    @Override
    public int getItemCount() {
        return mData == null ? 0 : mData.size();
    }
}

三、ViewPager2 数据源

        创建一个 Fragment 来作为 ViewPager2 的数据源。

public class MyFragment extends Fragment{


    /**
     * 的到当前Fragment 的一个实例
     */
    public static MyFragment newInstance(int position){
        Bundle bundle = new Bundle();
        bundle.putInt("Position", position);
        MyFragment fragment = new MyFragment();
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.d(TAG, tabIndex + "fragment" + "onCreate");
    }


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return super.onCreateView(inflater, container, savedInstanceState);
    }


}

四、MainActivity.java类

 1、初始化数据源。

/**
     * 初始化数据
     */
    private List<Fragment> initData(){
        mData = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            mData.add(MyFragment.newInstance(i));
        }
        return mData;
    }

2、ViewPager2 页面改变监听

        ViewPager2 里对页面改变的监听是 OnPageChangeCallback(); ViewPager 是 OnPageChangeListener(), 但是已经被废弃了。

        BottomNavigationView.setSelectedItemId(itemID) 根据itemID 设置选中的 item。当滑动 Fragment 时BottomNavigationView 的每个 item 也会相应的改变。做到每个Fragment 与 下面BottomNavigationView 的每个 item 绑定。

ViewPager2.OnPageChangeCallback onPageChangeCallback = new ViewPager2.OnPageChangeCallback() {
        @Override
        public void onPageSelected(int position) {
            super.onPageSelected(position);
            int itemID = R.id.fragment_1;
            switch (position) {
                case 0:
                    itemID = R.id.fragment_1;
                    break;
                case 1:
                    itemID = R.id.fragment_2;
                    break;
                case 2:
                    itemID = R.id.fragment_3;
                    break;
                case 3:
                    itemID = R.id.fragment_4;
                    break;
                case 4:
                    itemID = R.id.fragment_5;
                    break;
                default:
                    break;
            }
            //TODO 当Fragment滑动改变时底部的Tab也跟着改变
            mBottomNavigationView.setSelectedItemId(itemID);
        }
    };

3、BottomNavigationView 的每个 item 点击的监听

        对于底部导航栏 item 的监听应该是 OnNavigationItemSelectedListener但是该方法已经被 google 官方给废弃了所以这里用 OnItemSelectedListener 来代替。

        ViewPager.setCurrentItem() 方法设置当前 Viewpager 要加载的item (Fragment)这里做到 ViewPager2 的每一个 Fragment 与 底部导航栏的每个 item 绑定

NavigationBarView.OnItemSelectedListener onItemSelectedListener = new NavigationBarView.OnItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            // 点击Tab, 切换对应的 Fragment
            switch (item.getItemId()) {
                case R.id.fragment_1:
                    //TODO 当点击 Tab 时ViewPager 也切换到对应的 Fragment
                    mViewPager.setCurrentItem(0, true);
                    return true;
                case R.id.fragment_2:
                    mViewPager.setCurrentItem(1, true);
                    return true;
                case R.id.fragment_3:
                    mViewPager.setCurrentItem(2, true);
                    return true;
                case R.id.fragment_4:
                    mViewPager.setCurrentItem(3, true);
                    return true;
                case R.id.fragment_5:
                    mViewPager.setCurrentItem(4, true);
                    return true;
            }
            return false;
        }
    };

MainActivity的完整代码

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.widget.ViewPager2;

import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;

import com.example.viewpager2_demo.adapter.MyFragmentStateAdapter;
import com.example.viewpager2_demo.fragment.MyFragment;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView;

import java.util.ArrayList;
import java.util.List;

@RequiresApi(api = Build.VERSION_CODES.M)
public class MainActivity extends AppCompatActivity {


    private ViewPager2 mViewPager;
    private BottomNavigationView mBottomNavigationView;

    private List<Fragment> mData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mViewPager = findViewById(R.id.main_viewPager);
        mBottomNavigationView = findViewById(R.id.main_bottomNavigationView);
        // 设置适配器
        mViewPager.setAdapter(new MyFragmentStateAdapter(this, initData()));
        mViewPager.setOffscreenPageLimit(1); //设置页面缓存的个数默认1个
        //设置底部导航栏 item 点击的监听
        mBottomNavigationView.setOnItemSelectedListener(onItemSelectedListener);

        // 设置 ViewPager2 页面改变的监听
        mViewPager.registerOnPageChangeCallback(onPageChangeCallback);

    }

    ViewPager2.OnPageChangeCallback onPageChangeCallback = new ViewPager2.OnPageChangeCallback() {
        @Override
        public void onPageSelected(int position) {
            super.onPageSelected(position);
            int itemID = R.id.fragment_1;
            switch (position) {
                case 0:
                    itemID = R.id.fragment_1;
                    Log.d("HL", "1");
                    break;
                case 1:
                    itemID = R.id.fragment_2;
                    Log.d("HL", "2");
                    break;
                case 2:
                    itemID = R.id.fragment_3;
                    Log.d("HL", "3");
                    break;
                case 3:
                    itemID = R.id.fragment_4;
                    Log.d("HL", "4");
                    break;
                case 4:
                    itemID = R.id.fragment_5;
                    Log.d("HL", "5");
                    break;
                default:
                    break;
            }
            //TODO 当Fragment滑动改变时底部的Tab也跟着改变
            mBottomNavigationView.setSelectedItemId(itemID);
        }
    };

    NavigationBarView.OnItemSelectedListener onItemSelectedListener = new NavigationBarView.OnItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            // 点击Tab, 切换对应的 Fragment
            switch (item.getItemId()) {
                case R.id.fragment_1:
                    //TODO 当点击 Tab 时ViewPager 也切换到对应的 Fragment
                    mViewPager.setCurrentItem(0, true);
                    return true;
                case R.id.fragment_2:
                    mViewPager.setCurrentItem(1, true);
                    return true;
                case R.id.fragment_3:
                    mViewPager.setCurrentItem(2, true);
                    return true;
                case R.id.fragment_4:
                    mViewPager.setCurrentItem(3, true);
                    return true;
                case R.id.fragment_5:
                    mViewPager.setCurrentItem(4, true);
                    return true;
            }
            return false;
        }
    };

    /**
     * 初始化数据
     */
    private List<Fragment> initData(){
        mData = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            mData.add(MyFragment.newInstance(i));
        }
        return mData;
    }
}

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: android