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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM