美文网首页Android开发之路程序员Android知识
一句话搞定Android底部导航栏,一键绑定Fragment、V

一句话搞定Android底部导航栏,一键绑定Fragment、V

作者: Sakura_echo | 来源:发表于2017-08-12 09:50 被阅读9301次

    现在大多数App都会用到底部导航栏,比如常见的聊天工具QQ、微信、购物App等等,有了底部导航栏,用户可以随时切换界面,查看不同的内容。它的实现方式也很多,以前大多使用TabHost来实现,但是现在我们有很多更好的选择。

    常见的底部导航栏实现方式:
    1.使用LinearLayout + TextView实现了底部导航栏的效果
    2.使用RadioGroup + RadioButton实现了底部导航栏的效果
    3.利用BottomNavigationBar实现底部导航栏
    .......

    实现方式有很多,不过好像都只是关于下边Tab切换而已,没有实现Tab与界面的联动,用的时候还要自己手写这部分代码,麻烦不麻烦?

    作为一名注定要改变世界的程序猿,你让我天天写这个?这是不能忍的。

    更高,更快,更强

    就不能有个东西,能够一句话搞定Android底部导航栏,一键绑定Fragment、ViewPager吗?

    所以,这个BottomTabBar产生了。GitHub项目地址

    先来看下效果:


    简陋的演示.gif

    How to use:



    Step 1. Add the JitPack repository to your build file
    Add it in your root build.gradle at the end of repositories:
        allprojects {
            repositories {
                ...
                maven { url 'https://jitpack.io' }
            }
        }
    

    Step 2. Add the dependency

        dependencies {
             compile 'com.github.zhaolei9527:UseBottomTabBar:v1.0.4'
        }
    

    XML布局文件代码:

            <sakura.bottomtabbar.BottomTabBar
                android:id="@+id/BottomTabBar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
              ></sakura.bottomtabbar.BottomTabBar>
    

    控件可设置参数:

    参数名 描述
    tab_bar_background BottomTabBar的整体背景颜色
    tab_img_width 图片宽度
    tab_img_height 图片高度
    tab_font_size 文字尺寸
    tab_img_font_padding 图片文字间隔
    tab_padding_top 上边距
    tab_padding_bottom 下边距
    tab_isshow_divider 是否显示分割线
    tab_divider_height 分割线高度
    tab_divider_background 分割线背景
    tab_selected_color 选中的颜色
    tab_unselected_color 未选中的颜色

    Activity文件代码:

    导包:import sakura.bottomtabbar.BottomTabBar;

    绑定Fragment的:(一句话搞定有木有?)

                BottomTabBar.initFragmentorViewPager(getSupportFragmentManager())
                    .addReplaceLayout(R.id.fl_content)
                    .addTabItem("草莓", getResources().getDrawable(R.mipmap.icon01), getResources().getDrawable(R.mipmap.icon_round), FragmentA.class)
                    .addTabItem("凤梨", getResources().getDrawable(R.mipmap.icon02), getResources().getDrawable(R.mipmap.icon_round), FragmentB.class)
                    .addTabItem("樱桃", getResources().getDrawable(R.mipmap.icon03), getResources().getDrawable(R.mipmap.icon_round), FragmentC.class)
                    .addTabItem("香蕉", getResources().getDrawable(R.mipmap.icon04), getResources().getDrawable(R.mipmap.icon_round), FragmentD.class)
                    .commit();
    

    绑定ViewPager的:(一句话搞定有木有?)

            BottomTabBar.initFragmentorViewPager(viewpager)
                    .setChangeColor(getResources().getColor(R.color.colorAccent), getResources().getColor(R.color.colorPrimary))
                    .addTabItem("草莓", getResources().getDrawable(R.mipmap.icon01), getResources().getDrawable(R.mipmap.icon_round))
                    .addTabItem("凤梨", getResources().getDrawable(R.mipmap.icon02), getResources().getDrawable(R.mipmap.icon_round))
                    .addTabItem("樱桃", getResources().getDrawable(R.mipmap.icon03), getResources().getDrawable(R.mipmap.icon_round))
                    .addTabItem("香蕉", getResources().getDrawable(R.mipmap.icon04), getResources().getDrawable(R.mipmap.icon_round))
                    .commit(); 
    

    代码可配置参数方法:

    参数名 描述
    setImgSize 设置图片的尺寸
    setFontSize 设置文字的尺寸
    setTabPadding 设置Tab的padding值
    setChangeColor 设置选中未选中的颜色
    setTabBarBackgroundColor 设置BottomTabBar的整体背景颜色
    setTabBarBackgroundResource 设置BottomTabBar的整体背景图片
    isShowDivider 是否显示分割线
    setDividerHeight 设置分割线的高度
    setDividerColor 设置分割线的颜色

    很简单,对不对,你想干什么,我都替你干

    划重点,这个initFragmentorViewPager ( getSupportFragmentManager() | ViewPager)方法一定要第一个调用,没有这个初始化,后边什么也做不了。

    另外,上述实例的addTabItem是支持选中状态图片切换的方法,在此之外,还支持不需要切换图片的模式。

    /**
         * 添加TabItem
         * @param name  文字
         * @param imgId 图片id
         * @return
         */
        public BottomTabBar addTabItem(String name, int imgId){...}
    
    /**
         * 添加TabItem
         * @param name          文字
         * @param imgId         图片id
         * @param Fragmentclazz Fragment类
         * @return
         */
        public BottomTabBar addTabItem(String name, int imgId, Class Fragmentclazz){...}
    

    另外,考虑到在底部导航栏点击切换界面的需求之外的其他需求,BottomTabBar提供了点击事件的回调。

    ((BottomTabBar) findViewById(R.id.BottomTabBar))
                    .initFragmentorViewPager(getSupportFragmentManager())
                    .addReplaceLayout(R.id.fl_content)
                    .addTabItem("草莓", getResources().getDrawable(R.mipmap.icon01), getResources().getDrawable(R.mipmap.icon_round), FragmentA.class)
                    .addTabItem("凤梨", getResources().getDrawable(R.mipmap.icon02), getResources().getDrawable(R.mipmap.icon_round), FragmentB.class)
                    .addTabItem("樱桃", getResources().getDrawable(R.mipmap.icon03), getResources().getDrawable(R.mipmap.icon_round), FragmentC.class)
                    .addTabItem("香蕉", getResources().getDrawable(R.mipmap.icon04), getResources().getDrawable(R.mipmap.icon_round), FragmentD.class)
                    .setOnTabChangeListener(new BottomTabBar.OnTabChangeListener() {
                        @Override
                        public void onTabChange(int position, View V) {
                            Toast.makeText(FragmentActivity.this, "position:" + position, Toast.LENGTH_SHORT).show();
                        }
                    })
                    .commit();
    

    项目代码概览:

    获取xml配置样式 :

        public BottomTabBar(Context context, AttributeSet attrs) {
            super(context, attrs);
            this.context = context;
            TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.BottomTabBar);
            if (attributes != null) {
                //图片宽度
                imgWidth = attributes.getDimension(R.styleable.BottomTabBar_tab_img_width, dp2px(30));
                //图片高度
                imgHeight = attributes.getDimension(R.styleable.BottomTabBar_tab_img_height, dp2px(30));
                //文字尺寸
                fontSize = attributes.getDimension(R.styleable.BottomTabBar_tab_font_size, 14);
                //上边距
                paddingTop = attributes.getDimension(R.styleable.BottomTabBar_tab_padding_top, dp2px(2));
                //图片文字间隔
                fontImgPadding = attributes.getDimension(R.styleable.BottomTabBar_tab_img_font_padding, dp2px(3));
                //下边距
                paddingBottom = attributes.getDimension(R.styleable.BottomTabBar_tab_padding_bottom, dp2px(5));
                //分割线高度
                dividerHeight = attributes.getDimension(R.styleable.BottomTabBar_tab_divider_height, dp2px(1));
                //是否显示分割线
                isShowDivider = attributes.getBoolean(R.styleable.BottomTabBar_tab_isshow_divider, false);
                //选中的颜色
                selectColor = attributes.getColor(R.styleable.BottomTabBar_tab_selected_color, Color.parseColor("#F1453B"));
                //未选中的颜色
                unSelectColor = attributes.getColor(R.styleable.BottomTabBar_tab_unselected_color, Color.parseColor("#626262"));
                //BottomTabBar的整体背景
                tabBarBackgroundColor = attributes.getColor(R.styleable.BottomTabBar_tab_bar_background, Color.parseColor("#FFFFFF"));
                //分割线背景
                dividerBackgroundColor = attributes.getColor(R.styleable.BottomTabBar_tab_divider_background, Color.parseColor("#CCCCCC"));
                attributes.recycle();
            }
        }
    

    初始化View :

       private void initView() {
            mLayout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.bottom_tab_bar, null);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
            mLayout.setLayoutParams(layoutParams);
            mLayout.setBackgroundColor(tabBarBackgroundColor);
            addView(mLayout);
            mDivider = mLayout.findViewById(R.id.mDivider);
            mTabContent = (LinearLayout) mLayout.findViewById(R.id.mTabContent);
            if (isShowDivider) {
                LayoutParams dividerParams = new LayoutParams(LayoutParams.MATCH_PARENT, (int) dividerHeight);
                mDivider.setLayoutParams(dividerParams);
                mDivider.setBackgroundColor(dividerBackgroundColor);
                mDivider.setVisibility(VISIBLE);
            } else {
                mDivider.setVisibility(GONE);
            }
        }
    

    ViewPager模式添加Tab :

    public BottomTabBar addTabItem(final String name, Drawable selectdrawable, Drawable unselectdrawable) {
            selectdrawableList.add(selectdrawable);
            unselectdrawableList.add(unselectdrawable);
            LinearLayout TabItem = (LinearLayout) View.inflate(context, R.layout.tab_item, null);
            TabItem.setGravity(Gravity.CENTER);
            //设置TabItem标记
            TabItem.setTag(name);
            //添加标记至集合以作辨别
            tabIdList.add(String.valueOf(TabItem.getTag()));
            TabItem.setOnClickListener(this);
            //Tab图片样式及内容设置
            ImageView tab_item_img = (ImageView) TabItem.findViewById(R.id.tab_item_img);
            tab_item_imgparams = new LayoutParams((int) imgWidth, (int) imgHeight);
            tab_item_imgparams.topMargin = (int) paddingTop;
            tab_item_imgparams.bottomMargin = (int) fontImgPadding;
            tab_item_img.setLayoutParams(tab_item_imgparams);
            //Tab文字样式及内容设置
            TextView tab_item_tv = (TextView) TabItem.findViewById(R.id.tab_item_tv);
            tab_item_tvparams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            tab_item_tvparams.bottomMargin = (int) paddingBottom;
            tab_item_tv.setLayoutParams(tab_item_tvparams);
            tab_item_tv.setTextSize(fontSize);
            tab_item_tv.setText(name);
            if (tabIdList.size() == 1) {
                tab_item_tv.setTextColor(selectColor);
                tab_item_img.setBackground(selectdrawable);
            } else {
                tab_item_tv.setTextColor(unSelectColor);
                tab_item_img.setBackground(unselectdrawable);
            }
            TabItem.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f));
            mTabContent.addView(TabItem);
            return this;
        }
    

    Fragment模式添加Tab :

      public BottomTabBar addTabItem(final String name, Drawable selectdrawable, Drawable unselectdrawable, Class fragmentClass) {
            selectdrawableList.add(selectdrawable);
            unselectdrawableList.add(unselectdrawable);
            Class<?> clazz = null;
            try {
                clazz = Class.forName(fragmentClass.getName());
                Fragment fragment = (Fragment) clazz.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            FragmentList.add(fragmentClass);
            LinearLayout TabItem = (LinearLayout) View.inflate(context, R.layout.tab_item, null);
            TabItem.setGravity(Gravity.CENTER);
            //设置TabItem标记
            TabItem.setTag(name);
            //添加标记至集合以作辨别
            tabIdList.add(String.valueOf(TabItem.getTag()));
            TabItem.setOnClickListener(this);
            //Tab图片样式及内容设置
            ImageView tab_item_img = (ImageView) TabItem.findViewById(R.id.tab_item_img);
            tab_item_imgparams = new LayoutParams((int) imgWidth, (int) imgHeight);
            tab_item_imgparams.topMargin = (int) paddingTop;
            tab_item_imgparams.bottomMargin = (int) fontImgPadding;
            tab_item_img.setLayoutParams(tab_item_imgparams);
            //Tab文字样式及内容设置
            TextView tab_item_tv = (TextView) TabItem.findViewById(R.id.tab_item_tv);
            tab_item_tvparams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            tab_item_tvparams.bottomMargin = (int) paddingBottom;
            tab_item_tv.setLayoutParams(tab_item_tvparams);
            tab_item_tv.setTextSize(fontSize);
            tab_item_tv.setText(name);
            if (tabIdList.size() == 1) {
                tab_item_tv.setTextColor(selectColor);
                tab_item_img.setBackground(selectdrawable);
            } else {
                tab_item_tv.setTextColor(unSelectColor);
                tab_item_img.setBackground(unselectdrawable);
            }
            TabItem.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f));
            mTabContent.addView(TabItem);
            return this;
        }
    
    

    Fragment切换处理 :

        private void relaceFrament(int i) {
            Class aClass = FragmentList.get(i);
            Class<?> clazz = null;
            try {
                clazz = Class.forName(aClass.getName());
                Fragment Fragment = (Fragment) clazz.newInstance();
                android.support.v4.app.FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
                fragmentTransaction.replace(mReplaceLayout, Fragment);
                fragmentTransaction.commit();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    Tab点击事件处理 :

        @Override
        public void onClick(View v) {
            for (int i = 0; i < tabIdList.size(); i++) {
                if (tabIdList.get(i).equals(v.getTag())) {
                    if (mViewpager != null) {
                        //绑定ViewPager
                        mViewpager.setCurrentItem(i);
                    }
                    if (mFragmentManager != null) {
                        if (mReplaceLayout == 0) {
                            throw new IllegalStateException(
                                    "Must input ReplaceLayout of mReplaceLayout");
                        }
                        relaceFrament(i);
                        changeTab(i);
                    }
                    //绑定点击监听回调
                    listener.onTabChange(i, v);
                }
            }
        }
    

    Tab选中更改样式 :

        private void changeTab(int position) {
            if (position + 1 > mTabContent.getChildCount()) {
                throw new IndexOutOfBoundsException("onPageSelected:" + (position + 1) +
                        ",of Max mTabContent ChildCount:" + mTabContent.getChildCount());
            }
            for (int i = 0; i < mTabContent.getChildCount(); i++) {
                View TabItem = mTabContent.getChildAt(i);
                if (i == position) {
                    ((TextView) TabItem.findViewById(R.id.tab_item_tv)).setTextColor(selectColor);
                    if (!selectdrawableList.isEmpty())
                        TabItem.findViewById(R.id.tab_item_img).setBackground(selectdrawableList.get(i));
                } else {
                    ((TextView) TabItem.findViewById(R.id.tab_item_tv)).setTextColor(unSelectColor);
                    if (!selectdrawableList.isEmpty())
                        TabItem.findViewById(R.id.tab_item_img).setBackground(unselectdrawableList.get(i));
                }
            }
        }
    

    总结

    代码整体满足了一句话搞定Android底部导航栏,一键绑定Fragment、ViewPager的功能,当然,

    有了需求才有了功能,有了想法才有了创作,你的反馈会是使我进步的最大动力。

    觉得还不够方便?还想要什么功能?告诉我!欢迎反馈,欢迎Star。源码入口: UseBottomTabBar-GitHub项目地址

    相关文章

      网友评论

        本文标题:一句话搞定Android底部导航栏,一键绑定Fragment、V

        本文链接:https://www.haomeiwen.com/subject/hnqrrxtx.html