Android开发过程中,特别是新开的项目,底部状态栏的切换使用的频率非常的高,主要的实现方式有:

    (1)、TabLayout + Fragment    (2)、FragmentTabHost + Fragment    (3)、BottomNavigationView + Fragment    (4)、RidioGroup + Fragment

这里我先介绍前面两种实现方式,后面两种后期再贴出实现方式。

一、使用TabLayout + Fragment + ViewPager实现

1、实现步骤:

    (1)、布局文件中定义TabLayout控件    (2)、定义切换的每个Fragment布局文件    (3)、定义切换的每个Fragment的Java类    (4)、定义TabLayoutMainActivity类    (5)、效果图演示

2、实现过程:

(1)、布局文件中定义TabLayout控件(activity_main.xml)

<?xml version="1.0" encoding="utf-8"?><LinearLayout 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"    android:orientation="vertical"    tools:context="com.showly.bottomnavigationbardemo.TabLayoutMainActivity">    <android.support.v4.view.ViewPager        android:id="@+id/viewpager_content_view"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1"        android:scrollbars="none" />    <android.support.design.widget.TabLayout        android:id="@+id/tab_layout_view"        android:layout_width="match_parent"        android:layout_height="50dp"        app:tabGravity="fill"        app:tabIndicatorHeight="0dp"        app:tabMode="fixed"        app:tabSelectedTextColor="#FB8081"        app:tabTextColor="#A0A0A0" /></LinearLayout>

(2)、定义切换的每个Fragment布局文件(fragment_frist.xml)

这里有四个Tab类别(首页、娱乐、游戏、我的),布局都类似,这里只贴出其中一个

<?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:background="#fff"    android:orientation="vertical">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:text="首页"        android:textColor="#000"/></RelativeLayout>

(3)、定义切换的每个Fragment的Java类(FristFragment.class)

这里的Java 类实现方式也相似,贴出其中一个

package com.showly.bottomnavigationbardemo.fragment;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import com.showly.bottomnavigationbardemo.R;public class FristFragment extends Fragment {    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment_frist, null);        return view;    }}

(4)、定义TabLayoutMainActivity类(TabLayoutMainActivity.class)

package com.showly.bottomnavigationbardemo;import android.os.Bundle;import android.support.design.widget.TabLayout;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 com.showly.bottomnavigationbardemo.fragment.FourthlyFragment;import com.showly.bottomnavigationbardemo.fragment.FristFragment;import com.showly.bottomnavigationbardemo.fragment.SecondFragment;import com.showly.bottomnavigationbardemo.fragment.ThirtlyFragment;public class TabLayoutMainActivity extends AppCompatActivity {    //未选中的Tab图片    private int[] unSelectTabRes = new int[]{R.drawable.i8live_menu_home_normal            , R.drawable.i8live_menu_information_normal, R.drawable.i8live_menu_game_normal, R.drawable.i8live_menu_personl_normal};    //选中的Tab图片    private int[] selectTabRes = new int[]{R.drawable.i8live_menu_home_press, R.drawable.i8live_menu_information_press            , R.drawable.i8live_menu_game_press, R.drawable.i8live_menu_personl_press};    //Tab标题    private String[] title = new String[]{"首页", "娱乐", "游戏", "我的"};    private ViewPager viewPager;    private TabLayout tabLayout;    private TabLayout.Tab tabAtOne;    private TabLayout.Tab tabAttwo;    private TabLayout.Tab tabAtthree;    private TabLayout.Tab tabAtfour;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        getSupportActionBar().hide();//隐藏掉整个ActionBar        setContentView(R.layout.activity_main);        initView();        initData();        initListener();    }    private void initView() {        viewPager = (ViewPager) findViewById(R.id.viewpager_content_view);        tabLayout = (TabLayout) findViewById(R.id.tab_layout_view);        //使用适配器将ViewPager与Fragment绑定在一起        viewPager.setAdapter(new MyFragmentPagerAdapter(getSupportFragmentManager()));        //将TabLayout与ViewPager绑定        tabLayout.setupWithViewPager(viewPager);      /*  //设置方式一:        //获取底部的单个Tab        tabAtOne = tabLayout.getTabAt(0);        tabAttwo = tabLayout.getTabAt(1);        tabAtthree = tabLayout.getTabAt(2);        tabAtfour = tabLayout.getTabAt(3);        //设置Tab图片        tabAtOne.setIcon(R.drawable.i8live_menu_home_press);        tabAttwo.setIcon(R.drawable.i8live_menu_information_normal);        tabAtthree.setIcon(R.drawable.i8live_menu_game_normal);        tabAtfour.setIcon(R.drawable.i8live_menu_personl_normal);*/        //设置方式二:        for (int i = 0; i < title.length; i++) {            if (i == 0) {                tabLayout.getTabAt(0).setIcon(selectTabRes[0]);            } else {                tabLayout.getTabAt(i).setIcon(unSelectTabRes[i]);            }        }    }    private void initData() {    }    private void initListener() {        //TabLayout切换时导航栏图片处理        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {            @Override            public void onTabSelected(TabLayout.Tab tab) {//选中图片操作                for (int i = 0; i < title.length; i++) {                    if (tab == tabLayout.getTabAt(i)) {                        tabLayout.getTabAt(i).setIcon(selectTabRes[i]);                        viewPager.setCurrentItem(i);                    }                }            }            @Override            public void onTabUnselected(TabLayout.Tab tab) {//未选中图片操作                for (int i = 0; i < title.length; i++) {                    if (tab == tabLayout.getTabAt(i)) {                        tabLayout.getTabAt(i).setIcon(unSelectTabRes[i]);                    }                }            }            @Override            public void onTabReselected(TabLayout.Tab tab) {            }        });    }    //自定义适配器    public class MyFragmentPagerAdapter extends FragmentPagerAdapter {        public MyFragmentPagerAdapter(FragmentManager fm) {            super(fm);        }        @Override        public Fragment getItem(int position) {            if (position == 1) {                return new SecondFragment();//娱乐            } else if (position == 2) {                return new ThirtlyFragment();//游戏            } else if (position == 3) {                return new FourthlyFragment();//我的            }            return new FristFragment();//首页        }        @Override        public int getCount() {            return title.length;        }        @Override        public CharSequence getPageTitle(int position) {            return title[position];        }    }}

(5)、效果图演示

二、使用FragmentTabHost+ Fragment + ViewPager实现

1、实现步骤:

    (1)、布局文件中定义FragmentTabHost控件    (2)、定义底部菜单栏布局    (3)、定义切换的每个Fragment布局文件    (4)、定义切换的每个Fragment的Java类    (5)、切换按钮的图片    (6)、定义FragmentTabHostMainActivity类    (7)、效果图演示

2、实现过程:

(1)、布局文件中定义FragmentTabHost控件(fragment_tabhost_activity.xml)

<?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:background="#fff"    android:orientation="vertical">    <android.support.v4.view.ViewPager        android:id="@+id/vp_pager"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1"        android:scrollbars="none" />    <android.support.v4.app.FragmentTabHost        android:id="@android:id/tabhost"        android:layout_width="match_parent"        android:background="#3000"        android:layout_height="65dp">        <FrameLayout            android:id="@android:id/tabcontent"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />    </android.support.v4.app.FragmentTabHost></LinearLayout>

(2)、定义底部菜单栏布局(tab_content.xml)

<?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:padding="2dp"    android:orientation="vertical">    <ImageView        android:id="@+id/iv_imageview"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center_horizontal"        android:background="@drawable/i8live_menu_home_normal" />    <TextView        android:id="@+id/tv_item"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center_horizontal"        android:layout_marginTop="5dp"        android:text="首页" /></LinearLayout>

(3)、定义切换的每个Fragment布局文件(fragment_frist.xml)
这里有四个Tab类别(首页、娱乐、游戏、我的),布局都类似,这里只贴出其中一个

<?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:background="#fff"    android:orientation="vertical">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:text="首页"        android:textColor="#000"/></RelativeLayout>

(4)、定义切换的每个Fragment的Java类(FristFragment.class)

这里的Java 类实现方式也相似,贴出其中一个

package com.showly.bottomnavigationbardemo.fragment;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import com.showly.bottomnavigationbardemo.R;public class FristFragment extends Fragment {    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment_frist, null);        return view;    }}

(5)、切换按钮的图片(tab_main.xml)
这里有四个是相似的,只贴出其中一个

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">   <!-- 切换选中之后的图片-->    <item android:drawable="@drawable/i8live_menu_home_press" android:state_selected="true"/>    <!-- 未选中的图片-->    <item android:drawable="@drawable/i8live_menu_home_normal"/></selector

(6)、定义FragmentTabHostMainActivity类(FragmentTabHostMainActivity.class)

package com.showly.bottomnavigationbardemo;import android.graphics.Color;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.app.FragmentTabHost;import android.support.v4.view.ViewPager;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TabHost;import android.widget.TabWidget;import android.widget.TextView;import com.showly.bottomnavigationbardemo.fragment.FourthlyFragment;import com.showly.bottomnavigationbardemo.fragment.FristFragment;import com.showly.bottomnavigationbardemo.fragment.SecondFragment;import com.showly.bottomnavigationbardemo.fragment.ThirtlyFragment;import java.util.ArrayList;import java.util.List;public class FragmentTabHostMainActivity extends FragmentActivity implements ViewPager.OnPageChangeListener, TabHost.OnTabChangeListener {    private int[] selectTabRes = new int[]{R.drawable.tab_main, R.drawable.tab_infomation            , R.drawable.tab_game, R.drawable.tab_personal};    //Tab标题    private String[] title = new String[]{"首页", "娱乐", "游戏", "我的"};    private Class fragmentArry[] = {FristFragment.class, SecondFragment.class, ThirtlyFragment.class, FourthlyFragment.class};    private List<Fragment> fragmentList = new ArrayList();    private ViewPager viewPager;    private FragmentTabHost tabHost;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.fragment_tabhost_activity);        initView();        initData();        initListener();    }    /**     * 初始化Fragment并给ViewPager添加适配器     */    private void initVaper() {        FristFragment fristFragment = new FristFragment();        SecondFragment secondFragment = new SecondFragment();        ThirtlyFragment thirtlyFragment = new ThirtlyFragment();        FourthlyFragment fourthlyFragment = new FourthlyFragment();        fragmentList.add(fristFragment);        fragmentList.add(secondFragment);        fragmentList.add(thirtlyFragment);        fragmentList.add(fourthlyFragment);        //ViewPager添加适配器        viewPager.setAdapter(new MyFragmentAdapter(getSupportFragmentManager(), fragmentList));        tabHost.getTabWidget().setDividerDrawable(null);    }    private void initView() {        viewPager = (ViewPager) findViewById(R.id.vp_pager);        tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);//绑定tabhost        tabHost.setup(this, getSupportFragmentManager(), R.id.vp_pager);//TabHost绑定viewpager        //获取item的个数        int count = title.length;        for (int i = 0; i < count; i++) {            //设置每个TabHost布局            TabHost.TabSpec tabSpec = tabHost.newTabSpec(title[i])                    .setIndicator(getTabItemView(i));            //item与fragment关联            tabHost.addTab(tabSpec, fragmentArry[i], null);            tabHost.setTag(i);        }        //初始化TabHost文字颜色        upDateTab(tabHost);        //给ViewPager设置适配器        initVaper();    }    /**     * 更新文字颜色。     *     * @param mTabHost     */    private void upDateTab(FragmentTabHost mTabHost) {        for (int i = 0; i < mTabHost.getTabWidget().getChildCount(); i++) {            TextView tv = (TextView) mTabHost.getTabWidget().getChildAt(i).findViewById(R.id.tv_item);            if (mTabHost.getCurrentTab() == i) {//选中                tv.setTextColor(Color.parseColor("#FF5959"));            } else {//不选中                tv.setTextColor(Color.parseColor("#777777"));            }        }    }    /**     * 设置每个Item布局     */    private View getTabItemView(int i) {        View view = LayoutInflater.from(this).inflate(R.layout.tab_content, null);        ImageView itemImg = (ImageView) view.findViewById(R.id.iv_imageview);        TextView itemText = (TextView) view.findViewById(R.id.tv_item);        itemImg.setBackgroundResource(selectTabRes[i]);        itemText.setText(title[i]);        return view;    }    private void initData() {    }    private void initListener() {        viewPager.addOnPageChangeListener(this);        tabHost.setOnTabChangedListener(this);    }    @Override    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {    }    @Override    public void onPageSelected(int position) {        TabWidget widget = tabHost.getTabWidget();        int oldFocusability = widget.getDescendantFocusability();        widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);//设置View覆盖子类控件而直接获得焦点        tabHost.setCurrentTab(position);//根据位置Postion设置当前的Tab        widget.setDescendantFocusability(oldFocusability);//设置取消分割线    }    @Override    public void onPageScrollStateChanged(int state) {    }    @Override    public void onTabChanged(String tabId) {        int position = tabHost.getCurrentTab();        viewPager.setCurrentItem(position);//把选中的Tab的位置赋给适配器,让它控制页面切换        upDateTab(tabHost);//设置TabHost文字颜色    }    /**     * 适配器     * */    public class MyFragmentAdapter extends FragmentPagerAdapter {        List<Fragment> list;        public MyFragmentAdapter(FragmentManager fm, List<Fragment> list) {            super(fm);            this.list = list;        }        @Override        public Fragment getItem(int position) {            return list.get(position);        }        @Override        public int getCount() {            return list.size();        }    }}

(7)、效果图演示

三、总结
这两种方式的实现已完成,实现起来相对还是比较简单的,后期有时间会把后面两种的实现方式补上。
Demo代码地址:底部公众号回复"底部状态栏切换"即可获取。


以下是个人公众号(longxuanzhigu),之后发布的文章会同步到该公众号,方便交流学习Android知识及分享个人爱好文章: