zoukankan      html  css  js  c++  java
  • android底部导航栏实现

    第一种用radiobutton实现

     https://wizardforcel.gitbooks.io/w3school-android/content/75.html

    布局文件,使用radiogroup

    <?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"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <View
            android:id="@+id/ly_top_bar"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="@color/colorPrimary"/>
    
    
        <RadioGroup
            android:layout_width="match_parent"
            android:layout_height="56dp"
            android:id="@+id/rg_tab_bar"
            android:layout_alignParentBottom="true"
            android:orientation="horizontal">
            <RadioButton
                android:id="@+id/rbb_1"
                style="@style/tab_menu_item"
                android:drawableTop="@drawable/qq"
                android:text="@string/jihua"/>
            <RadioButton
                android:id="@+id/rbb_2"
                style="@style/tab_menu_item"
                android:drawableTop="@drawable/pp"
                android:text="@string/dating"/>
            <RadioButton
                android:id="@+id/rbb_3"
                style="@style/tab_menu_item"
                android:drawableTop="@drawable/oo"
                android:text="@string/wode"/>
        </RadioGroup>
    
        <View
            android:id="@+id/div_tab_bar"
            android:layout_width="match_parent"
            android:layout_height="2px"
            android:layout_above="@id/rg_tab_bar" />
    
        <FrameLayout
            android:id="@+id/ly_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@id/div_tab_bar"
            android:layout_below="@id/ly_top_bar">
    
        </FrameLayout>
    
    </RelativeLayout>

    activity文件,每个界面是一个fragment

    package com.example.administrator.miaomiao;
    
    
    import android.graphics.drawable.Drawable;
    import android.support.v4.app.FragmentManager;
    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 allactivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {
        private RadioGroup rg_tab_bar;
        private RadioButton rb_1;
        private RadioButton rb_2;
        private RadioButton rb_3;
    
        //Fragment Object
        private Fragment1 fg1;
        private Fragment2 fg2;
        private Fragment3 fg3;
        private FragmentManager fManager;
    //    private Toolbar toolbar;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_allactivity);
            fManager = getSupportFragmentManager();
            rg_tab_bar = (RadioGroup) findViewById(R.id.rg_tab_bar);
            rg_tab_bar.setOnCheckedChangeListener(this);
            //获取第一个单选按钮,并设置其为选中状态
            rb_1 = (RadioButton) findViewById(R.id.rbb_1);
            rb_2 = (RadioButton) findViewById(R.id.rbb_2);
            rb_3 = (RadioButton) findViewById(R.id.rbb_3);
            rb_1.setChecked(true);
            initView();
        }
    
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            FragmentTransaction fTransaction = fManager.beginTransaction();
            hideAllFragment(fTransaction);
            switch (checkedId){
                case R.id.rbb_1:
                    if(fg1 == null){
                        fg1 = new Fragment1();
                        fTransaction.add(R.id.ly_content,fg1, "Fragment1");
                    }else{
                        fTransaction.show(fg1);
                    }
                    break;
                case R.id.rbb_2:
                    if(fg2 == null){
                        fg2 = new Fragment2();
                        fTransaction.add(R.id.ly_content,fg2, "Fragment2");
                    }else{
                        fTransaction.show(fg2);
                    }
                    break;
                case R.id.rbb_3:
                    if(fg3 == null){
                        fg3 = new Fragment3();
                        fTransaction.add(R.id.ly_content,fg3, "Fragment3");
                    }else{
                        fTransaction.show(fg3);
                    }
                    break;
            }
            fTransaction.commit();
        }
    
        //隐藏所有Fragment
        private void hideAllFragment(FragmentTransaction fragmentTransaction){
            if(fg1 != null)fragmentTransaction.hide(fg1);
            if(fg2 != null)fragmentTransaction.hide(fg2);
    //        if(fg3 != null)fragmentTransaction.hide(fg3);
            if(fg3 != null)fragmentTransaction.hide(fg3);
        }
    
        private void initView() {
            //定义底部标签图片大小和位置
            Drawable drawable_news = getResources().getDrawable(R.drawable.qq);
            //当这个图片被绘制时,给他绑定一个矩形 ltrb规定这个矩形
            drawable_news.setBounds(0, 0, 40, 40);
            //设置图片在文字的哪个方向
            rb_1.setCompoundDrawables(null, drawable_news, null, null);
    
            //定义底部标签图片大小和位置
            Drawable drawable_live = getResources().getDrawable(R.drawable.pp);
            //当这个图片被绘制时,给他绑定一个矩形 ltrb规定这个矩形
            drawable_live.setBounds(0, 0, 40, 40);
            //设置图片在文字的哪个方向
            rb_2.setCompoundDrawables(null, drawable_live, null, null);
    
            //定义底部标签图片大小和位置
            Drawable drawable_tuijian = getResources().getDrawable(R.drawable.oo);
            //当这个图片被绘制时,给他绑定一个矩形 ltrb规定这个矩形
            drawable_tuijian.setBounds(0, 0, 40, 40);
            //设置图片在文字的哪个方向
            rb_3.setCompoundDrawables(null, drawable_tuijian, null, null);
    
    
        }
    
    
    }

    第二种在github上搜的,博客地址为https://www.jianshu.com/p/ce8e09cda486

    因为公司好多项目会用到底部导航栏,大都千篇一律,无非2-5个Tab(可能会有些点击动画、红点提示或者中间多个加号)总是重复相同的操作...所以...很懒的我希望几行代码就能实现这个效果(少敲一行是一行)

    效果图

     
    轻松实现.gif

    实现

    • 依赖

    Step 1. Add it in your root build.gradle at the end of repositories:

        allprojects {
            repositories {
                ...
                maven { url 'https://jitpack.io' }
            }
        }
    

    Step 2. Add the dependency

        implementation 'com.github.forvv231:EasyNavigation:1.0.3'
    
    1、基础版

    xml

    <com.next.easynavigation.view.EasyNavigationBar
         android:id="@+id/navigationBar"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
    </com.next.easynavigation.view.EasyNavigationBar>
    

    注:因EasyNavigationBar包含ViewPager,需设置充满

    Activity

    private String[] tabText = {"首页", "发现", "消息", "我的"};
    //未选中icon
    private int[] normalIcon = {R.mipmap.index, R.mipmap.find, R.mipmap.message, R.mipmap.me};
    //选中时icon
    private int[] selectIcon = {R.mipmap.index1, R.mipmap.find1, R.mipmap.message1, R.mipmap.me1};
    
    private List<android.support.v4.app.Fragment> fragments = new ArrayList<>();
    
    navigationBar = findViewById(R.id.navigationBar);
    
    fragments.add(new FirstFragment());
    fragments.add(new SecondFragment());
    fragments.add(new FirstFragment());
    fragments.add(new SecondFragment());
    
    navigationBar.titleItems(tabText)
                    .normalIconItems(normalIcon)
                    .selectIconItems(selectIcon)
                    .fragmentList(fragments)
                    .fragmentManager(getSupportFragmentManager())
                    .build();
    

    怎么样 是不是很Easy啊( ̄▽ ̄)~*

    2、加号版本
    private String[] tabText = {"首页", "发现", "", "消息", "我的"};
    //未选中icon
    private int[] normalIcon = {R.mipmap.index, R.mipmap.find, R.mipmap.add_image, R.mipmap.message, R.mipmap.me};
    //选中时icon
    private int[] selectIcon = {R.mipmap.index1, R.mipmap.find1, R.mipmap.add_image, R.mipmap.message1, R.mipmap.me1};
    
    navigationBar.titleItems(tabText)
                    .normalIconItems(normalIcon)
                    .selectIconItems(selectIcon)
                    .fragmentList(fragments)
                    .mode(EasyNavigationBar.MODE_ADD)
                    .fragmentManager(getSupportFragmentManager())
                    .build();
    
    • 资源数组中添加文字和图片,不需要文字可传空串
    • mode设置为EasyNavigationBar.MODE_ADD
     
    基础版和加号版本.png
    3、中间添加自定义view
     View view = LayoutInflater.from(this).inflate(R.layout.custom_add_view, null);
    
     navigationBar.titleItems(tabText)
                    .normalIconItems(normalIcon)
                    .selectIconItems(selectIcon) 
                    .fragmentManager(getSupportFragmentManager())
                    .fragmentList(fragments)
                    .mode(EasyNavigationBar.MODE_ADD_VIEW)
                    .addCustomView(view)
                    .addLayoutRule(EasyNavigationBar.RULE_CENTER)
                    .build();
    
    • addCustomView添加自定义好的view
    • mode设置为EasyNavigationBar.MODE_ADD_VIEW


       
      自定义中间按钮

    属性

    • 什么?不过瘾?看看下面给你提供可以更改的属性,满足你的需求(xml也可设置)
    navigationBar.titleItems(tabText)      //必传  Tab文字集合
                    .normalIconItems(normalIcon)   //必传  Tab未选中图标集合
                    .selectIconItems(selectIcon)   //必传  Tab选中图标集合
                    .fragmentList(fragments)       //必传  fragment集合
                    .fragmentManager(getSupportFragmentManager())     //必传
                    .iconSize(20)     //Tab图标大小
                    .tabTextSize(10)   //Tab文字大小
                    .tabTextTop(2)     //Tab文字距Tab图标的距离
                    .normalTextColor(Color.parseColor("#666666"))   //Tab未选中时字体颜色
                    .selectTextColor(Color.parseColor("#333333"))   //Tab选中时字体颜色
                    .scaleType(ImageView.ScaleType.CENTER_INSIDE)  //同 ImageView的ScaleType
                    .navigationBackground(Color.parseColor("#80000000"))   //导航栏背景色
                    .onTabClickListener(new EasyNavigationBar.OnTabClickListener() {   //Tab点击事件  return true 页面不会切换
                        @Override
                        public boolean onTabClickEvent(View view, int position) {
                            return false;
                        }
                    })
                    .smoothScroll(false)  //点击Tab  Viewpager切换是否有动画
                    .canScroll(false)    //Viewpager能否左右滑动
                    .mode(EasyNavigationBar.MODE_ADD)   //默认MODE_NORMAL 普通模式  //MODE_ADD 带加号模式
                    .anim(Anim.ZoomIn)                //点击Tab时的动画
                    .addIconSize(36)    //中间加号图片的大小
                    .addLayoutHeight(100)   //包含加号的布局高度 背景透明  所以加号看起来突出一块
                    .navigationHeight(40)  //导航栏高度
                    .lineHeight(100)         //分割线高度  默认1px
                    .lineColor(Color.parseColor("#ff0000"))
                    .addLayoutRule(EasyNavigationBar.RULE_BOTTOM) //RULE_CENTER 加号居中addLayoutHeight调节位置 EasyNavigationBar.RULE_BOTTOM 加号在导航栏靠下
                    .addLayoutBottom(10)   //加号到底部的距离
                    .hasPadding(true)    //true ViewPager布局在导航栏之上 false有重叠
                    .hintPointLeft(-3)  //调节提示红点的位置hintPointLeft hintPointTop(看文档说明)
                    .hintPointTop(-3)
                    .hintPointSize(6)    //提示红点的大小
                    .msgPointLeft(-10)  //调节数字消息的位置msgPointLeft msgPointTop(看文档说明)
                    .msgPointTop(-10)
                    .msgPointTextSize(9)  //数字消息中字体大小
                    .msgPointSize(18)    //数字消息红色背景的大小
                    .addAlignBottom(true)  //加号是否同Tab文字底部对齐  RULE_BOTTOM时有效;
                    .addTextTopMargin(50)  //加号文字距离加号图片的距离
                    .addTextSize(15)      //加号文字大小
                    .addNormalTextColor(Color.parseColor("#ff0000"))    //加号文字未选中时字体颜色
                    .addSelectTextColor(Color.parseColor("#00ff00"))    //加号文字选中时字体颜色
                    .build();
    

    需求(简单列举几个)

    需求1:红点或数字消息提示
    //数字消息大于99显示99+ 小于等于0不显示,取消显示则可以navigationBar.setMsgPointCount(2, 0)
    navigationBar.setMsgPointCount(2, 109);
    navigationBar.setMsgPointCount(0, 5);
    //红点提示 第二个参数控制是否显示
    navigationBar.setHintPoint(3, true);
    

    清除也可以这样(这样的方法名可能直观些)

    //清除第四个红点提示
    navigationBar.clearHintPoint(3);
    //清除第一个数字消息
    navigationBar.clearMsgPoint(0);
    

    数字消息的位置可通过msgPointLeft、msgPointTop来控制,默认这两个值为Tab图标的一半


     
    数字消息位置属性说明.png

    注:红点提示同理,通过hintPointLeft和hintPointTop两个属性调节位置

    需求2:半开放式登录、点击“我的”Tab、不切换页面、需要进行登录操作
      .onTabClickListener(new EasyNavigationBar.OnTabClickListener() {
                        @Override
                        public boolean onTabClickEvent(View view, int position) {
                            if (position == 3) {
                                Toast.makeText(AddActivity.this, "请先登录", Toast.LENGTH_SHORT).show();
                                return true;
                            }
                            return false;
                        }
                    })
    

    onTabClickEvent方法中return true则拦截事件、不进行页面切换

    注:这种情况canScroll不能设置为true、否则滑动仍会切换页面

    需求3:加号突出(以前这种比较多,现在好多都在导航栏里面、找了好多app...)
     
    简书和爱奇艺两种加号.png
    • 像图中的两种需求,如何调整加号的位置呢

    提供两种解决方式、addLayoutRule设置属性RULE_CENTER和RULE_BOTTOM两种


     
    新建位图图像 (2).png

    1、RULE_CENTER
    中间加号(红色圆圈)相对红色框居中,可通过addLayoutHeight调节加号的位置,此时addLayoutBottom属性无效

    2、RULE_BOTTOM
    中间加号(红色圆圈)在红色框底部,可通过addLayoutBottom属性调节加号到底部的距离,从而改变加号的位置;

     <com.next.easynavigation.view.EasyNavigationBar
            android:id="@+id/navigationBar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:Easy_addIconSize="40dp"
            app:Easy_navigationHeight="60dp"
            app:Easy_addLayoutHeight="80dp"
            app:Easy_addLayoutBottom="10dp"
            app:Easy_addLayoutRule="RULE_CENTER">
    
    • 中间加号下面文字和其他Tab文字对齐

    addAlignBottom属性可设置加号文字和其他Tab底部对齐。
    注:addLayoutRule= RULE_BOTTOM时、addAlignBottom才有效

     
    类似全民k歌.jpg
    需求4:加号旋转
    • EasyNavigationBar.MODE_ADD模式下

    可使用 navigationBar.getAddImage()获取到加号直接进行操作;

    • EasyNavigationBar.MODE_ADD_VIEW模式下

    可使用navigationBar.getCustomAddView()对你添加的view进行操作;

    navigationBar.getCustomAddView().animate().rotation(180).setDuration(400);
    
    需求5:点击第一个页面中的按钮、跳转到第二个页面并执行其中的方法(部分人可选择无视)

    第二个页面添加方法供Activity调用

     //提示消息
     public void showToast(String str) {
         Toast.makeText(getActivity(), str, Toast.LENGTH_SHORT).show();
     }
    

    第一个页面中调用代码

     //跳转第二个页面
     ((AddActivity) getActivity()).getNavigationBar().selectTab(1);
     //调用第二个页面的方法
     ((SecondFragment) (((AddActivity) getActivity()).getNavigationBar().getAdapter().getItem(1))).showToast("嘻嘻哈哈嗝");
    

    使用注意事项

    若运行后EasyNavigationBar为空白、则查看Log信息提示修改

    • EasyNavigationBar.MODE_ADD模式下

    中间图片资源及文字同其他tab一起传入,若不需要文字、传空串即可,三个资源数组数量应该相等且数量应为奇数(因为有加号存在)。

    若想点击加号实现Fragment切换,addAsFragment设置为true、此时Fragment数量=资源数量

    若点击加号不切换Fragment,跳转界面或弹出底部菜单(此时加号文字图片状态不会变),addAsFragment应为false(默认false),此时Fragment数量=资源数量-1

    • EasyNavigationBar.MODE_ADD_VIEW模式下

    若想点击加号实现Fragment切换,addAsFragment设置为true、此时Fragment数量=资源数量+1

    若点击加号不切换Fragment,addAsFragment应为false(默认false),实现跳转界面或弹出底部菜单(此时),FragmentFragment数量=资源数量


    更新(1.0.0)

    1、中间加号下可添加文字;
    2、中间加号位置可添加自定义View;
    3、可设置点击加号后同其他Tab一样切换Fragment;

    • 移除addIcon属性、添加中间的图片文字同Tab一样
    • 移除onAddClickListener、监听事件同Tab、实现onTabClickListener
    • 新增addAlignBottom属性(加号是否同Tab文字底部对齐 RULE_BOTTOM时有效)
    • 新增addTextTopMargin属性(加号文字距离加号图片的距离)
    • 新增addTextSize属性(加号文字大小)
    • 新增addNormalTextColor属性(加号文字未选中时字体颜色)
    • 新增addSelectTextColor属性(加号文字选中时字体颜色)
    • 更改addIconBottom方法名为addLayoutBottom
    • 更改addIconRule方法名为addLayoutRule

    Demo

    github:https://github.com/forvv231/EasyNavigation

    apk: https://fir.im/7r4d


    By the way

    • 本Demo中仿微博弹出菜单实现

    参考https://github.com/DuShuYuan/PlusMenu

  • 相关阅读:
    8-kubernetes-安全
    6-kubernetes网络
    5-kunernetes资源调度
    4-K8S 部署Java应用及应用程序生命周期管理
    3-kubernetes监控与日志管理
    2-K8S常用命令
    1-kubeadm部署1.18.0单master集群
    部署Prometheus+Grafana监控
    微信小程序学习
    vue 中使用 @scroll事件 没有用
  • 原文地址:https://www.cnblogs.com/downrainsun/p/11901863.html
Copyright © 2011-2022 走看看