Android底部导航栏的实现---------6种方法+底部大按钮跳转(最全集合)

现在的应用大多需要一个底部导航图来完成人性化的设置,这篇文章就来看一下比较流行的底部导航的实现:

目录:

一.BottomNavigationView+ViewPager+fragment

二.BottomNavigationBar+ViewPager(FrameLayout)+fragment

三.TabLayout+fragment+viewPager

四.FragmentTabHost+ViewPager+fragment

五.RadioGroup+Radiobutton+ViewPager+fragment

六.RadioGroup+Radiobutton+FrameLayout+fragment(实现底部栏中间大按钮跳转页面)

七.TextView+LinearLayout+FrameLayout


fragment文件

fragment布局文件就是放了一个Textview显示:


代码:

 @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.layout_fragment,null);
        TextView textView = view.findViewById(R.id.text);
        textView.setText(R.string.alert);
        return view;
    }
    public static Fragment newInstance(){
        AlertFragment homeFragment = new AlertFragment();
        return homeFragment;
    }

其他的fragmentt和此类似

一.BottomNavigationView+ViewPager+fragment


Android底部导航栏的实现---------6种方法+底部大按钮跳转(最全集合)_第1张图片

uGoogle 发布了专门用来实现底部导航的控件,那就是BottomNavigationView,BottomNavigationView符合Material 风格,有着炫酷的切换动画,但是5.0以上可以使用,BottomNavigationView使用较为简单:

新建一个Activity,选择BottomNavigation Activity,自动给你添加控件和代码

而BottomNavigationView 的Tab是通过menu 的方式添加的,所有看一下menu文件:

 

    

    

    
    

Activity中的代码

 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;
                case R.id.alert:
                    mTextMessage.setText(R.string.alert);
                    return true;
                case R.id.email:
                    mTextMessage.setText(R.string.email);
                    return true;
            }
            return false;
        }
    };

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

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

XML文件:




    

    

BottomNavigationView使用较为简单,不需要你自己定义控件,只需要自己修改他给你定义的menu文件和回调方法

二.BottomNavigationBar+ViewPager(FrameLayout)+fragment


Android底部导航栏的实现---------6种方法+底部大按钮跳转(最全集合)_第2张图片

BottomNavigationBar和BottomNavigationView都是Google公司自己退出的,名字还是如此的相似,但是我却没有找出他们的联系和区别,这就让我很迷茫了,有知道的大佬可以告告我

现在说一下它的使用

在Gradle中添加

implementation 'com.ashokvarma.android:bottom-navigation-bar:2.0.2'

布局文件(FrameLayout)

 
    
    

使用FrameLayout

Activity类:

private int imageViewArray[] = {R.drawable.ic_home_black_24dp, R.drawable.ic_dashboard_black_24dp, R.drawable.ic_notifications_black_24dp, R.drawable.email, R.drawable.dialog_alert_icon};
    private String[] strings = {"Home", "DashBoard", "Notification", "Email", "Alert"};
    FragmentTransaction transaction;
    FragmentManager manager;
    BottomNavigationBar bar;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bottom_navigation_bar_test);
        bar = findViewById(R.id.bottombar);
//角标,如同QQ的红点
        final TextBadgeItem mBadgeItem = new TextBadgeItem()
                .setBorderWidth(4)
                .setAnimationDuration(200)
                .setBackgroundColorResource(R.color.red)
                .setHideOnSelect(false)
                .setText("0");


        bar.addItem(new BottomNavigationItem(imageViewArray[0], strings[0]).setActiveColorResource(R.color.black).setBadgeItem(mBadgeItem))
                .addItem(new BottomNavigationItem(imageViewArray[1], strings[1]).setActiveColorResource(R.color.colorPrimary))
                .addItem(new BottomNavigationItem(imageViewArray[2], strings[2]).setActiveColorResource(R.color.orange))
                .addItem(new BottomNavigationItem(imageViewArray[3], strings[3]).setActiveColorResource(R.color.purple))
                .addItem(new BottomNavigationItem(imageViewArray[4], strings[4]).setActiveColorResource(R.color.red))
                .setFirstSelectedPosition(0)
                .initialise();

        bar.setTabSelectedListener(new BottomNavigationBar.OnTabSelectedListener() {
            @Override
            public void onTabSelected(int position) {
                manager = getSupportFragmentManager();
                transaction = manager.beginTransaction();
                switch (position){

                    case 0:
                        transaction.replace(R.id.framelayout, HomeFragment.newInstance());
                        mBadgeItem.hide();

                        break;
                    case 1:
                        transaction.replace(R.id.framelayout, DashboardFragment.newInstance());
                        mBadgeItem.show();
                        break;
                    case 2:
                        transaction.replace(R.id.framelayout, NotificationFragment.newInstance());
                        break;
                    case 3:
                        transaction.replace(R.id.framelayout, EmailFragment.newInstance());
                        break;
                    case 4:
                       transaction.replace(R.id.framelayout,AlertFragment.newInstance());
                        break;
                }
                transaction.commit();
           
            }

            @Override
            public void onTabUnselected(int position) {

            }

            @Override
            public void onTabReselected(int position) {

            }
        });
//设置初始页面
        setDefaultFragment();


    }

设置初始界面

private void setDefaultFragment() {
        manager = getSupportFragmentManager();
        transaction = manager.beginTransaction();
        transaction.replace(R.id.framelayout, HomeFragment.newInstance());
        transaction.commit();
    }

使用ViewPager

布局文件

将FrameLayout改成ViewPager



    

Activity类

只需要将回调方法重写,以及初始化fragment和viewPager

 private List fragments;
    private ViewPager viewPager;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bottom_navigation_bar_test);
        bar = findViewById(R.id.bottombar);
        initPager();

        final TextBadgeItem mBadgeItem = new TextBadgeItem()
                .setBorderWidth(4)
                .setAnimationDuration(200)
                .setBackgroundColorResource(R.color.red)
                .setHideOnSelect(false)
                .setText("0");
        bar.addItem(new BottomNavigationItem(imageViewArray[0], strings[0]).setActiveColorResource(R.color.black).setBadgeItem(mBadgeItem))
                .addItem(new BottomNavigationItem(imageViewArray[1], strings[1]).setActiveColorResource(R.color.colorPrimary))
                .addItem(new BottomNavigationItem(imageViewArray[2], strings[2]).setActiveColorResource(R.color.orange))
                .addItem(new BottomNavigationItem(imageViewArray[3], strings[3]).setActiveColorResource(R.color.purple))
                .addItem(new BottomNavigationItem(imageViewArray[4], strings[4]).setActiveColorResource(R.color.red))
                .setFirstSelectedPosition(0)
                .initialise();
        bar.setTabSelectedListener(new BottomNavigationBar.OnTabSelectedListener() {
            @Override
            public void onTabSelected(int position) {               
                viewPager.setCurrentItem(position);
            }

            @Override
            public void onTabUnselected(int position) {

            }

            @Override
            public void onTabReselected(int position) {

            }
        });

        setDefaultFragment();


    }

    private void initPager() {
        viewPager = findViewById(R.id.viewpager);
        fragments = new ArrayList();
        fragments.add(HomeFragment.newInstance());
        fragments.add(DashboardFragment.newInstance());
        fragments.add(NotificationFragment.newInstance());
        fragments.add(EmailFragment.newInstance());
        fragments.add(AlertFragment.newInstance());
        viewPager.setAdapter(new MyFragmentPagerAdapter(getSupportFragmentManager(), fragments));
        viewPager.setCurrentItem(0);
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                bar.selectTab(position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

     private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
        private List lists;

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

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

        public MyFragmentPagerAdapter(FragmentManager fm, List datas) {
            super(fm);
            lists = datas;
        }

        public MyFragmentPagerAdapter() {
            super(null);
        }
    }

三.TabLayout+fragment+viewPager


Android底部导航栏的实现---------6种方法+底部大按钮跳转(最全集合)_第3张图片

要实现这样一个底部导航栏,大家最容易想到的当然就是TabLayout,Tab 切换嘛,TabLayout 就是专门干这个事的,不过TabLayout 默认是带有Indicator的,我们是不需要的,因此需要把它去掉

去掉默认的Indicator直接设置app:tabIndicatorHeight属性的值为0就行了

布局文件



    

Activity类:

private TabLayout tabLayout;
    private List fragments;
    private ViewPager viewPager;
    private FragmentPagerAdapter adapter;
    private String[] strings ={"Home","DashBoard","Notification","Email","Alert"};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tablayout_test);
        initView();
    }

    private void initView() {
        tabLayout = findViewById(R.id.tablayout);
        fragments = new ArrayList();
        fragments.add(HomeFragment.newInstance());
        fragments.add(DashboardFragment.newInstance());
        fragments.add(NotificationFragment.newInstance());
        fragments.add(EmailFragment.newInstance());
        fragments.add(AlertFragment.newInstance());
        viewPager = findViewById(R.id.viewpager);
        adapter = new TitleFragmentPagerAdapter(getSupportFragmentManager(),fragments,strings);
        viewPager.setAdapter(adapter);

        tabLayout.setupWithViewPager(viewPager);
        onTabItemSelected();
    }

    private void onTabItemSelected() {
        for (int i =0;i mFragmentList = null;

        private String[] titles;

        public TitleFragmentPagerAdapter(FragmentManager mFragmentManager,
                                         List fragmentList) {
            super(mFragmentManager);
            mFragmentList = fragmentList;
        }


        public TitleFragmentPagerAdapter(FragmentManager mFragmentManager,
                                         List fragmentList, String[] titles) {
            super(mFragmentManager);
            mFragmentList = fragmentList;
            this.titles = titles;
        }

        @Override
        public int getCount() {
            return mFragmentList.size();
        }


        @Override
        public Fragment getItem(int position) {

            Fragment fragment = null;
            if (position < mFragmentList.size()) {
                fragment = mFragmentList.get(position);
            } else {
                fragment = mFragmentList.get(0);
            }
            return fragment;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            if (titles != null && titles.length > 0)
                return titles[position];
            return null;
        }
    }

 

四.FragmentTabHost+ViewPager+fragment


Android底部导航栏的实现---------6种方法+底部大按钮跳转(最全集合)_第4张图片

FragmentTabHost 可能是大家实现底部导航栏用得最多的一种方式,特别是在TabLayout 和 BottomNavigation 出来之前,是比较老的实现底部导航栏的方式,同时也是使用最多的一种

布局文件


    
        

        

    

Activity

 private ViewPager mViewPager;
    private List fragments;
    private FragmentTabHost host;
    private int imageViewArray[] = { R.drawable.ic_home_black_24dp, R.drawable.ic_dashboard_black_24dp,R.drawable.ic_notifications_black_24dp,R.drawable.email,R.drawable.dialog_alert_icon};
    private String[] strings ={"Home","DashBoard","Notification","Email","Alert"};
    private FragmentPagerAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_tab_host_test);
        initview();
    }
    private void initview(){
        mViewPager = findViewById(R.id.viewpager);
        fragments = new ArrayList();
        fragments.add(HomeFragment.newInstance());
        fragments.add(DashboardFragment.newInstance());
        fragments.add(NotificationFragment.newInstance());
        fragments.add(EmailFragment.newInstance());
        fragments.add(AlertFragment.newInstance());
        adapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),fragments);
        mViewPager.setAdapter(adapter);
        mViewPager.addOnPageChangeListener(pageChangeListener);
        host = findViewById(android.R.id.tabhost);
        host.setup(this,getSupportFragmentManager(),R.id.viewpager);
        host.getTabWidget().setDividerDrawable(null);
        host.setOnTabChangedListener(onTabChangeListener);
        int count = strings.length;
        for (int i = 0;i lists;
        @Override
        public Fragment getItem(int position) {
            return lists == null?null:lists.get(position);
        }

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

        public MyFragmentPagerAdapter(FragmentManager fm, List datas){
            super(fm);
            lists = datas;
        }
        public  MyFragmentPagerAdapter(){
            super(null);
        }
    }

TabHost需要你自己定义一个布局文件来显示图片和文字




    

    


 

五.RadioGroup+Radiobutton+ViewPager+fragment

Android底部导航栏的实现---------6种方法+底部大按钮跳转(最全集合)_第5张图片

RadioGroup +RadioButtom 是做单选的 所以用RadioGroup + RadioButton 来实现底部导航栏也是一种方式。但是要去掉他的默认样式,所以自己要定义一个样式:

自定义样式

布局文件

 
    


        
            

            

            

            

            

        

Activity类

private ViewPager mViewPager;
    private RadioGroup radioGroup;
    private List fragments;
    private FragmentPagerAdapter adapter;

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

    private void initview() {
        mViewPager = findViewById(R.id.viewpager);
        radioGroup = findViewById(R.id.radiogroup);
        fragments = new ArrayList();
        fragments.add(HomeFragment.newInstance());
        fragments.add(DashboardFragment.newInstance());
        fragments.add(NotificationFragment.newInstance());
        fragments.add(EmailFragment.newInstance());
        fragments.add(AlertFragment.newInstance());
        adapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), fragments);
        mViewPager.setAdapter(adapter);
        mViewPager.addOnPageChangeListener(pageChangeListener);
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                for (int i = 0; i < group.getChildCount(); i++) {
                    if (group.getChildAt(i).getId() == checkedId) {
                        mViewPager.setCurrentItem(i);
                        return;
                    }
                }

            }
        });
    }

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

    private ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            if (radioGroup.getChildAt(position) instanceof RadioButton) {
                RadioButton radioButton = (RadioButton) radioGroup.getChildAt(position);
                radioButton.setChecked(true);
            } else {

            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    };

    private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
        private List lists;

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

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

        public MyFragmentPagerAdapter(FragmentManager fm, List datas) {
            super(fm);
            lists = datas;
        }

        public MyFragmentPagerAdapter() {
            super(null);
        }
    }

 

六.RadioGroup+Radiobutton+FrameLayout+fragment(实现底部栏中间大按钮跳转页面)

Android底部导航栏的实现---------6种方法+底部大按钮跳转(最全集合)_第6张图片

和第5个类似,但是在radiogroup添加一个view占格,然后创建个imageview覆盖view

布局文件




    
        

        

        

        

        

    
    

Activity


    private RadioGroup radioGroup;
    private SparseArray fragments;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_test);
        initview();
    }
    private void initview(){
        radioGroup = findViewById(R.id.radiogroup);
        fragments = new SparseArray() {};
        fragments.append(R.id.radio1, HomeFragment.newInstance());
        fragments.append(R.id.radio2, DashboardFragment.newInstance());
        fragments.append(R.id.radio3, NotificationFragment.newInstance());
        fragments.append(R.id.radio5, AlertFragment.newInstance());
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                        fragments.get(checkedId)).commit();
            }
        });
        getSupportFragmentManager().beginTransaction().add(R.id.fragment_container,
                fragments.get(R.id.radio1)).commit();
        ImageView imageView = findViewById(R.id.imageview);
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(IntentTest.this,TabLayoutTest.class));
            }
        });
    }

这个我viewpager没有实现出来,所以就是抄的别人的(小小的吐槽一下)

第二个方法

在布局文件的根节点添加:

android:clipChildren="false"

clipChildren这个属性是在容器里面限制子控件能不能越界绘制,默认是true,也是可以实现底部中间大按钮的,此处就不给代码,诸位可以试试

七.TextView+LinearLayout+FrameLayout

此方法就是自己一个个定义TextView和Imageview来显示

这篇文章讲可以参考:https://blog.csdn.net/student9128/article/details/53463355

总结

本文总结了实现底部导航栏的6种方式,其中TabLayout 和,BottomNavigationView和BottomNavigationBar 是Android 5.0 以后添加的新控件,符合Material 设计规范,如果是Materail 风格的,可以考虑用这两种实现

还有就是知道BottomNavigationView和BottomNavigationBar 区别和联系的大佬可以告我一下的

demo


这是demo,需要的可以看一下

你可能感兴趣的:(安卓)