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

  1. 云栖社区>
  2. 博客>
  3. 正文

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

sakura_echo 2018-11-08 11:21:45 浏览858
展开阅读全文

现在大多数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项目地址

网友评论

登录后评论
0/500
评论
sakura_echo
+ 关注