底部导航栏的使用(RadioGroup + ViewPager

2019-12-09  本文已影响0人  禄眠

介绍

在前面已经介绍过使用BottomNavigationView实现底部导航栏,但是并不能左右滑动切换页面,当然配合ViewPager也是可以实现的,可以参考这篇博客:

ViewPager+BottomNavigationView+Fragment实现底部导航栏

今天的底部导航栏的实现方式是:RadioGroup + ViewPager + Fragment

使用

首先创建三个Fragment备用:FirstFragmnetSecondFragmentThirdFragment

然后修改activity_main.xml布局文件

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

    <RadioGroup
        android:id="@+id/radioGroup"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <RadioButton
            android:id="@+id/radioButton3"
            style="@style/RadioButtonStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:drawableTop="@drawable/bottom_nav_bg"
            android:text="导航1"
            android:textColor="@drawable/bottom_nav_text" />

        <RadioButton
            android:id="@+id/radioButton2"
            style="@style/RadioButtonStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawableTop="@drawable/bottom_nav_bg"
            android:text="导航2"
            android:textColor="@drawable/bottom_nav_text" />

        <RadioButton
            android:id="@+id/radioButton"
            style="@style/RadioButtonStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawableTop="@drawable/bottom_nav_bg"
            android:text="导航3"
            android:textColor="@drawable/bottom_nav_text" />
    </RadioGroup>

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/radioGroup"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

这里只要关注RadioButton部分即可

<RadioButton
            android:id="@+id/radioButton3"
            style="@style/RadioGroupButtonStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:drawableTop="@drawable/bottom_nav_bg"
            android:text="导航1"
            android:textColor="@drawable/bottom_nav_text" />

首先自定义了一个主题,用于设置一些通用的属性:

<style name="RadioButtonStyle">
        <!-- 去掉button 默认样式-->
        <item name="android:button">@null</item>
        <item name="android:gravity">center</item>
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_weight">1</item>
        <item name="android:textSize">12sp</item>
        <item name="android:textColor">#000000</item>
        <!--去掉默认的点击效果-->
        <item name="android:background">@null</item>
        <!--设置按钮与RadioGroup的边距-->
        <item name="android:layout_margin">10dp</item>
    </style>

然后设置了一个背景图,显示在文本上方:android:drawableTop="@drawable/bottom_nav_bg"

这是一个资源文件bottom_nav_bg.xml,设置选中/未选中时显示的图片

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

同理,android:textColor="@drawable/bottom_nav_text"用于设置字体颜色,也是一个资源文件bottom_nav_text.xml

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

剩下的代码为了方便全部写到MainActivity中:

package com.wzl.bottomnavigationvpdemo;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.RadioButton;
import android.widget.RadioGroup;

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

/**
 * RadioGroup + ViewPager
 */
public class MainActivity extends AppCompatActivity {

    private ViewPager viewPager;
    private FragmentPagerAdapter mAdapter;
    private RadioGroup radioGroup;
    private List<Fragment> mFragments;
    private final String TAG = "MainActivity";


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

    private void initView() {

        viewPager = findViewById(R.id.viewPager);
        radioGroup = findViewById(R.id.radioGroup);

        mFragments = new ArrayList<>(3);
        // 在Fragment中写一个单例模式即可
        mFragments.add(FirstFragment.newInstance());
        mFragments.add(SecondFragment.newInstance());
        mFragments.add(ThirdFragment.newInstance());

        mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), mFragments);
        viewPager.setAdapter(mAdapter);

        viewPager.addOnPageChangeListener(mPageChangeListener);
        radioGroup.setOnCheckedChangeListener(mCheckedChangeListener);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        viewPager.removeOnPageChangeListener(mPageChangeListener);
    }

    private class MyFragmentPagerAdapter extends FragmentPagerAdapter {

        private List<Fragment> mList;

        MyFragmentPagerAdapter(FragmentManager fm, List<Fragment> list) {
            super(fm);
            mList = list;
        }

        @NonNull
        @Override
        public Fragment getItem(int position) {
            return mList == null ? null : mList.get(position);
        }

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

    // ViewPager的页面切换监听事件
    private ViewPager.OnPageChangeListener mPageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            // ViewPager发生变化的同时,修改RadioButton的选中状态
            RadioButton radioButton = (RadioButton) radioGroup.getChildAt(position);
            radioButton.setChecked(true);
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    };
    
    // RadioGroup中的RadioButton选中变化监听事件
    private RadioGroup.OnCheckedChangeListener mCheckedChangeListener = new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            // 遍历所有元素,匹配后改变ViewPager的显示
            for (int i = 0; i < group.getChildCount(); i++) {
                if (group.getChildAt(i).getId() == checkedId) {
                    viewPager.setCurrentItem(i);
                    return;
                }
            }
        }
    };

}

单例模式示例:

private static FirstFragment fragment = null;
...
static synchronized FirstFragment newInstance(String name) {
        return fragment == null ? new FirstFragment() : fragment;
    }

效果图

GIF.gif
上一篇下一篇

猜你喜欢

热点阅读