android底部导航栏

本博客 供个人学习使用 参考 博客

https://blog.csdn.net/jxq1994/article/details/52573506
https://blog.csdn.net/afei__/article/details/80950288

第一种方式 BottomNavigationView android自带的底部导航栏。
新建Activity时选择Bottom Navigation Activity就会自动使用BottomNavigationView并生成相应代码。

布局如下

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Style1Activity">

    <TextView
        android:id="@+id/message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/activity_horizontal_margin"
        android:layout_marginLeft="@dimen/activity_horizontal_margin"
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:text="@string/title_home"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/navigation" />

</android.support.constraint.ConstraintLayout>

一个android.support.design.widget.BottomNavigationView控件指明了app:menu="@menu/navigation就是 底部 布局文件

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

    <item
        android:id="@+id/navigation_home"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/title_home" />

    <item
        android:id="@+id/navigation_dashboard"
        android:icon="@drawable/ic_dashboard_black_24dp"
        android:title="@string/title_dashboard" />

    <item
        android:id="@+id/navigation_notifications"
        android:icon="@drawable/ic_notifications_black_24dp"
        android:title="@string/title_notifications" />

</menu>

可以添加修改item达到自己预期效果
activity如下

public class Style1Activity extends AppCompatActivity {

    private TextView mTextMessage;

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.navigation_home:
                    mTextMessage.setText(R.string.title_home);
                    return true;
                case R.id.navigation_dashboard:
                    mTextMessage.setText(R.string.title_dashboard);
                    return true;
                case R.id.navigation_notifications:
                    mTextMessage.setText(R.string.title_notifications);
                    return true;
            }
            return false;
        }
    };

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

        mTextMessage = (TextView) findViewById(R.id.message);
        BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    }

}

修改 onNavigationItemSelected 事件应该能满足 大部分需求 比如 使用 Fragment 替换当前之类

private void replaceFragment(Fragment fragment){
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    transaction.replace(R.id.frame, fragment);
    transaction.commit();
}

自带的导航

第二个方法 LinearLayout + TextView实现了底部导航栏的效果
首先 创建好资源
在drawable 目录下 新建 Drawable resource file 为四个底层导航栏图片文字设置选项
如table_menu_note.xml 设计记帐本 导航 选择与未选择的图片展示

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/note_selected" android:state_selected="true" />
    <item android:drawable="@mipmap/note_black" />
</selector>

table_menu_note_text.xml 设计记账本 选择与未选择的文字颜色展示 @color文件夹中可设置颜色

    <?xml version="1.0" encoding="utf-8"?>
   <selector xmlns:android="http://schemas.android.com/apk/res/android">
       <item android:color="@color/text_blue" android:state_selected="true"/>
       <item android:color="@color/text_gray" />
   </selector>

可 根据需要 将 底部导航栏 的 图片 文字 依次写出

创建背景资源table_menu_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true">
        <shape>
            <solid android:color="#FFC4C4C4"/>
        </shape>
    </item>
    <item>
        <shape>
            <solid android:color="@color/colorPrimary" />
        </shape>
    </item>
</selector>

资源准备
个人感觉 这里面最重要的就是 Drawable resource file文件的创建 是一个selector 包含属性 android:state_selected=“true”
当控件使用该资源时 可在活动中设置 控件的选中与否 使用 控件.setSelected(trye|false) 。然后控件 会根据设置的selector展现不同效果。

还需要创建 一个 自定义的 Fragment 该Fragment 用于展示不同界面
布局文件

<?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"
    android:background="#dcdcdc">


    <TextView
        android:id="@+id/txt_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:gravity="center"
        android:text="呵呵"
        android:textColor="@color/text_blue"
        android:textSize="20sp"/>

</LinearLayout>

只有一个文本框用于展示 因为 重点 是 底部导航栏 fragment 只是用于展示接着创建一个继承Fragment的自定义类
该类可根据类方法getInstance获取 MyFragment实例。

public class MyFragment extends Fragment {

    private TextView mTextView;

    // 官方不建议 使用  带有参数的构造方法  如果强行使用  官方建议Fragment.setArguments(Bundle bundle)传递参数
    //    @SuppressLint("ValidFragment") 放在 类的开头
//    public MyFragment(String content){
//        this.content = content;
//    }


    // 获取MyFragment实例 并设置 参数
    public static MyFragment getInstance(String content){
        Bundle bundle = new Bundle();
        bundle.putString("content", content);

        MyFragment myFragment = new MyFragment();
        myFragment.setArguments(bundle);

        return myFragment;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment, container, false);
        Bundle bundle = getArguments();
        if(bundle != null){
            String content = bundle.getString("content");
            mTextView = view.findViewById(R.id.txt_content);
            mTextView.setText(content);
        }
        return view;
    }
}

将需要的资源 准备好 开始编写 布局文件

<?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=".Style2Activity">

    <FrameLayout
        android:id="@+id/fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/tab_menu"
        android:layout_marginBottom="2dp" />


    <LinearLayout
        android:id="@+id/tab_menu"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:orientation="horizontal"
        android:layout_alignParentBottom="true">

        <TextView
            android:id="@+id/txt_note"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/table_menu_bg"
            android:drawableTop="@drawable/table_menu_note"
            android:drawablePadding="3dp"
            android:gravity="center"
            android:text="记账"
            android:textColor="@drawable/table_menu_note_text" />

        <TextView
            android:id="@+id/txt_table"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/table_menu_bg"
            android:drawablePadding="3dp"
            android:drawableTop="@drawable/table_menu_table"
            android:gravity="center"
            android:textColor="@drawable/table_menu_table_text"
            android:text="图表"/>

        <TextView
            android:id="@+id/txt_find"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/table_menu_bg"
            android:drawablePadding="3dp"
            android:drawableTop="@drawable/table_menu_find"
            android:gravity="center"
            android:textColor="@drawable/table_menu_find_text"
            android:text="发现"/>

        <TextView
            android:id="@+id/txt_mine"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/table_menu_bg"
            android:drawablePadding="3dp"
            android:drawableTop="@drawable/table_menu_mine"
            android:gravity="center"
            android:textColor="@drawable/table_menu_mine_text"
            android:text="我的"/>

    </LinearLayout>


</RelativeLayout>

每个TextView 的android:background android:drawableTop android:textColor 都使用的selector。可根据选中与否展示不同效果。 使用 FrameLayout 来展示 Fragment 实例

布局文件创建完成 开始Activity文件

package com.mingrisoft.bottomtabbar;

import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.TextView;

// TextView

public class Style2Activity extends AppCompatActivity implements View.OnClickListener {

    private TextView tabNote;
    private TextView tabTable;
    private TextView tabFind;
    private TextView tabMine;

    // 四个碎片
    private MyFragment myFragment1, myFragment2, myFragment3, myFragment4;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);  //什么意思
        setContentView(R.layout.activity_style2);

        bindView();

        tabNote.setSelected(true);
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment, MyFragment.getInstance("添加账单"));
        transaction.commit();
    }

    // UI 初始化 与 事件 绑定
    private void bindView(){
        tabNote = findViewById(R.id.txt_note);
        tabTable = findViewById(R.id.txt_table);
        tabFind = findViewById(R.id.txt_find);
        tabMine = findViewById(R.id.txt_mine);


        tabNote.setOnClickListener(this);
        tabTable.setOnClickListener(this);
        tabFind.setOnClickListener(this);
        tabMine.setOnClickListener(this);
    }

    //重置所有文本的选中状态
    public void selected(){
        tabNote.setSelected(false);
        tabTable.setSelected(false);
        tabFind.setSelected(false);
        tabMine.setSelected(false);
    }

    //隐藏所有Fragment
    public void hideAllFragment(FragmentTransaction transaction){
        if(myFragment1 != null){
            transaction.hide(myFragment1);
        }
        if(myFragment2 != null){
            transaction.hide(myFragment2);
        }
        if(myFragment3 != null){
            transaction.hide(myFragment3);
        }
        if(myFragment4 != null){
            transaction.hide(myFragment4);
        }
    }

    @Override
    public void onClick(View v) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        hideAllFragment(transaction);
        selected();
        switch (v.getId()){
            case R.id.txt_note:
                tabNote.setSelected(true);  // 设置 为 选中状态
                if(myFragment1 == null){    // 如果 myFragment1 不存在 就创建一个
                    myFragment1 = MyFragment.getInstance("添加账单");
                    transaction.add(R.id.fragment, myFragment1);    // 将碎片添加进R.id.fragment的碎片管理器
                } else {    // 如果存在 就 显示出来  因为点击事件一旦触发 就会将 所有碎片隐藏
                    transaction.show(myFragment1);
                }
                break;
            case R.id.txt_table:
                tabTable.setSelected(true);  // 设置 为 选中状态
                if(myFragment2 == null){    // 如果 myFragment1 不存在 就创建一个
                    myFragment2 = MyFragment.getInstance("展示报表");
                    transaction.add(R.id.fragment, myFragment2);    // 将碎片添加进R.id.fragment的碎片管理器
                } else {    // 如果存在 就 显示出来  因为点击事件一旦触发 就会将 所有碎片隐藏
                    transaction.show(myFragment2);
                }
                break;
            case R.id.txt_find:
                tabFind.setSelected(true);  // 设置 为 选中状态
                if(myFragment3 == null){
                    myFragment3 = MyFragment.getInstance("发现");
                    transaction.add(R.id.fragment, myFragment3);
                } else {
                    transaction.show(myFragment3);
                }
                break;
            case R.id.txt_mine:
                tabMine.setSelected(true);  // 设置 为 选中状态
                if(myFragment4 == null){
                    myFragment4 = MyFragment.getInstance("我的");
                    transaction.add(R.id.fragment, myFragment4);
                } else {
                    transaction.show(myFragment4);
                }
                break;
        }
        transaction.commit();
    }
}

创建了 4 个 Fragment 实例 根据 TextView的点击事件 使用 FragmentTransaction 对四个碎片进行隐藏和展示。就能达到底部导航栏效果。

第三个方法 RadioGroup 代替 TextView
与 第二个方法 类似
首先 要将 几个资源文件修改一下 因为 RadioGroup 中 选中属性是 checked 不是 selected 如修改tab_menu_note.xml文件

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

在原基础上加一句 即可其他的文字颜色 背景色 修改 同上。

准备工作完成 布局文件

<?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=".Style3Activity">

    <FrameLayout
        android:id="@+id/fragment_rg"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/rb_group"
        android:layout_marginBottom="2dp">

    </FrameLayout>

    <RadioGroup
        android:id="@+id/rb_group"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_alignParentBottom="true"
        android:background="@color/color_grey"
        android:orientation="horizontal">
        <RadioButton
            android:id="@+id/rb_note"
            style="@style/tab_menu_item"
            android:drawableTop="@drawable/table_menu_note"
            android:text="记账"/>

        <RadioButton
            android:id="@+id/rb_table"
            style="@style/tab_menu_item"
            android:drawableTop="@drawable/table_menu_table"
            android:text="图表"/>

        <RadioButton
            android:id="@+id/rb_find"
            style="@style/tab_menu_item"
            android:drawableTop="@drawable/table_menu_find"
            android:text="发现"/>

        <RadioButton
            android:id="@+id/rb_mine"
            style="@style/tab_menu_item"
            android:drawableTop="@drawable/table_menu_mine"
            android:text="个人"/>
    </RadioGroup>


</RelativeLayout>

其实与第二种方法 没什么 太大区别 只是使用RadioButton 代替了 TextView
Activity文件。。。

package com.mingrisoft.bottomtabbar;

import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.RadioButton;
import android.widget.RadioGroup;

public class Style3Activity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {

    private RadioGroup rbTab;
    private MyFragment myFragment1,myFragment2, myFragment3, myFragment4;

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

        bindView();
    }

    // UI 初始化 与 事件 绑定
    private void bindView(){
        rbTab = findViewById(R.id.rb_group);
        // 最为重要的一句  为 RadioGroup注册监听 判断哪个组件为选中状态 checked
        rbTab.setOnCheckedChangeListener(this);

        // 默认设置rbNote为选中状态
        ((RadioButton) findViewById(R.id.rb_note)).setChecked(true);
    }

    //隐藏所有Fragment
    public void hideAllFragment(FragmentTransaction transaction){
        if(myFragment1 != null){
            transaction.hide(myFragment1);
        }
        if(myFragment2 != null){
            transaction.hide(myFragment2);
        }
        if(myFragment3 != null){
            transaction.hide(myFragment3);
        }
        if(myFragment4 != null){
            transaction.hide(myFragment4);
        }
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        hideAllFragment(transaction);
        switch (checkedId){
            case R.id.rb_note:
                if(myFragment1 == null){
                    myFragment1 = MyFragment.getInstance("记账");
                    transaction.add(R.id.fragment_rg, myFragment1);
                } else {
                    transaction.show(myFragment1);
                }
                break;
            case R.id.rb_table:
                if(myFragment2 == null){
                    myFragment2 = MyFragment.getInstance("图表");
                    transaction.add(R.id.fragment_rg, myFragment2);
                } else {
                    transaction.show(myFragment2);
                }
                break;
            case R.id.rb_find:
                if(myFragment3 == null){
                    myFragment3 = MyFragment.getInstance("发现");
                    transaction.add(R.id.fragment_rg, myFragment3);
                } else {
                    transaction.show(myFragment3);
                }
                break;
            case R.id.rb_mine:
                if(myFragment4 == null){
                    myFragment4 = MyFragment.getInstance("个人");
                    transaction.add(R.id.fragment_rg, myFragment4);
                } else {
                    transaction.show(myFragment4);
                }
                break;
        }
        transaction.commit();
    }
    
}

监听事件变成了RadioGroup 的 onCheckedChanged其他与第二种方式 一致。

第四个 方法 ViewPager + RadioGroup
使用ViewPager 代替 了 Framlayout 使页面 有 滑动效果
布局文件

<?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=".Style4Activity">

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_fragments"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/rg_tabs">
        
    </android.support.v4.view.ViewPager>
    
    <RadioGroup
        android:id="@+id/rg_tabs"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_alignParentBottom="true"
        android:background="@color/color_grey"
        android:orientation="horizontal">
        
        <RadioButton
            android:id="@+id/tab_note"
            style="@style/tab_menu_item"
            android:checked="true"
            android:drawableTop="@drawable/table_menu_note"
            android:text="@string/tab_note"/>

        <RadioButton
            android:id="@+id/tab_table"
            style="@style/tab_menu_item"
            android:drawableTop="@drawable/table_menu_table"
            android:text="@string/tab_table"/>

        <RadioButton
            android:id="@+id/tab_find"
            style="@style/tab_menu_item"
            android:drawableTop="@drawable/table_menu_find"
            android:text="@string/tab_find"/>

        <RadioButton
            android:id="@+id/tab_mine"
            style="@style/tab_menu_item"
            android:drawableTop="@drawable/table_menu_mine"
            android:text="@string/tab_mine"/>

    </RadioGroup>

</RelativeLayout>

Activity 文件

package com.mingrisoft.bottomtabbar;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.RadioButton;
import android.widget.RadioGroup;

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

public class Style4Activity extends AppCompatActivity {

    private ViewPager mViewPager;
    private RadioGroup mRadioGroup;


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

        initView();
    }

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

    public void initView(){

        mViewPager = findViewById(R.id.vp_fragments);
        mRadioGroup = findViewById(R.id.rg_tabs);

        // 碎片列表
        // 初始化碎片 和 碎片列表
        List<MyFragment> myFragments = new ArrayList<>(4);
        myFragments.add(MyFragment.getInstance("记账"));
        myFragments.add(MyFragment.getInstance("报表"));
        myFragments.add(MyFragment.getInstance("发现"));
        myFragments.add(MyFragment.getInstance("我的"));

        // 管理碎片列表的Adapter
        // 初始化FragmentPagerAdapter与ViewPager
        FragmentPagerAdapter mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), myFragments);
        mViewPager.setAdapter(mAdapter);

        // 分别设置 监听
        mRadioGroup.setOnCheckedChangeListener(mCheckedChangeListener);
        mViewPager.addOnPageChangeListener(mPageChangeListener);
    }

    // 页面改变事件监听  主要是与  RadioGroup 保持一致
    private ViewPager.OnPageChangeListener mPageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int i, float v, int i1) {

        }

        @Override
        public void onPageSelected(int i) {
            // 界面的 序号 对应 RadioGroup 中 RadioButton 的 顺序
            RadioButton radioButton = (RadioButton) mRadioGroup.getChildAt(i);
            radioButton.setChecked(true);
        }

        @Override
        public void onPageScrollStateChanged(int i) {

        }
    };

    // RadioGroup中RadioButton 选中按钮的 改变  保持 和  ViewPager 中 碎片对应一致
    private RadioGroup.OnCheckedChangeListener mCheckedChangeListener = new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            // 找到CheckId 对应的 编号  也可以使用 switch
            for(int i=0; i < group.getChildCount(); i++){
                if(group.getChildAt(i).getId() == checkedId){
                    // 相等则 找到 选中RadioButton对应的 编号顺序  设置mViewPager
                    mViewPager.setCurrentItem(i);
                    break;
                }
            }
        }
    };

    private class MyFragmentPagerAdapter extends FragmentPagerAdapter{

        private List<MyFragment> mList;

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

        @Override
        public Fragment getItem(int i) {
            // mList 为空 就 返回空  否则返回当前 项
            return this.mList == null ? null : this.mList.get(i);
        }

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

}

主要设置 了 自定义的 FragmentPagerAdapter 来对 ViewPager 进行管理。 然后 对 RadioGroup 和 ViewPager 分别设置了监听事件。。。 使界面 的 切换 与 Button 的点击 保持一致 ViewPager 可以是 页面 左右滑动。

以上 效果图相差不大
样式1

**带页面跳转 功能的 底部导航 **
如下图样式二
中间的图片 找不到 资源 就用了 系统 图表 只是表明 该按钮比较特别 。

<?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=".Style4Activity">

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_fragments"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/rg_tabs">

    </android.support.v4.view.ViewPager>

    <RadioGroup
        android:id="@+id/rg_tabs"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_alignParentBottom="true"
        android:background="@color/color_grey"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/tab_note"
            style="@style/tab_menu_item"
            android:checked="true"
            android:drawableTop="@drawable/table_menu_note"
            android:text="@string/tab_note"/>

        <RadioButton
            android:id="@+id/tab_table"
            style="@style/tab_menu_item"
            android:drawableTop="@drawable/table_menu_table"
            android:text="@string/tab_table"/>

        <View
            style="@style/tab_menu_item"/>

        <RadioButton
            android:id="@+id/tab_find"
            style="@style/tab_menu_item"
            android:drawableTop="@drawable/table_menu_find"
            android:text="@string/tab_find"/>

        <RadioButton
            android:id="@+id/tab_mine"
            style="@style/tab_menu_item"
            android:drawableTop="@drawable/table_menu_mine"
            android:text="@string/tab_mine"/>

    </RadioGroup>

    <ImageView
        android:id="@+id/iv_sign"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:contentDescription="@string/str_register"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@android:color/transparent"
        android:src="@mipmap/ic_launcher" />

</RelativeLayout>

RadioGroup 中 先填充 一个 View 然后 用一个 ImageView 覆盖 这样 不会遮挡住其他底部导航按钮。
即使 多了个 界面 跳转 按钮 原理 与 第四 个 其实 也一样 不过 需要注意
ViewPager 与 RadioGroup 的 事件监听

package com.mingrisoft.bottomtabbar;

import android.content.Intent;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;

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

public class Style5Activity extends AppCompatActivity {

    private ImageView mImageView;
    private RadioGroup mRadioGroup;
    private ViewPager mViewPager;

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

        initView();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mViewPager.removeOnPageChangeListener(pageChangeListener);
    }

    private void initView(){
        mImageView = findViewById(R.id.iv_sign);
        mRadioGroup = findViewById(R.id.rg_tabs);
        mViewPager = findViewById(R.id.vp_fragments);


        List<MyFragment> myFragments = new ArrayList<>(4);
        myFragments.add(MyFragment.getInstance("记账"));
        myFragments.add(MyFragment.getInstance("图表"));
        myFragments.add(MyFragment.getInstance("发现"));
        myFragments.add(MyFragment.getInstance("我的"));

        FragmentPagerAdapter adapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), myFragments);
        mViewPager.setAdapter(adapter);

        mImageView.setOnClickListener(clickListener);
        mViewPager.addOnPageChangeListener(pageChangeListener);
        mRadioGroup.setOnCheckedChangeListener(checkedChangeListener);

    }

    View.OnClickListener clickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.iv_sign:
                    Intent intent = new Intent(Style5Activity.this, Style1Activity.class);
                    startActivity(intent);
                    break;
            }
        }
    };

    RadioGroup.OnCheckedChangeListener checkedChangeListener = new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            switch (checkedId){
                case R.id.tab_note:
                    mViewPager.setCurrentItem(0);
                    break;
                case R.id.tab_table:
                    mViewPager.setCurrentItem(1);
                    break;
                case R.id.tab_find:
                    mViewPager.setCurrentItem(2);
                    break;
                case R.id.tab_mine:
                    mViewPager.setCurrentItem(3);
                    break;
            }
        }
    };

    ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int i, float v, int i1) {

        }

        @Override
        public void onPageSelected(int i) {
            if(i < 2){
                RadioButton radioButton = (RadioButton) mRadioGroup.getChildAt(i);
                radioButton.setChecked(true);
            } else {
                RadioButton radioButton = (RadioButton) mRadioGroup.getChildAt(i+1);
                radioButton.setChecked(true);
            }
        }

        @Override
        public void onPageScrollStateChanged(int i) {

        }
    };

    class MyFragmentPagerAdapter extends FragmentPagerAdapter{

        private List<MyFragment> mList;

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

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

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

}

一定要注意这里的 RadioGroup 中间有一个占位的 View
对 RadioGroup.OnCheckedChangeListener的监听 使用的 switch 而不是 for循环 因为使用 for 循环 的话 因为 RadioGroup 的 子控件数量 与 碎片 数量不一致 会 越界
对 ViewPager.OnPageChangeListener 事件的监听 加上一个 判断 对 i 的判断

底部导航 差不多 应该就这么多 。 希望自己 能够 记住如何使用

  • 5
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值