android中如何封裝一個好用的動態導航欄

《android中如何打造一個動態的底部導航欄》
在上一篇只是教大家一些基礎的東西,今天來完成一個真正的動態底部導航欄的項目,本項目還是會分幾步來完成,不懂的可以根據步驟一步一步的來,每個步驟都會解釋清楚,相信大家一定會學習到一些東西,相信學習之後,自己也能有自己的一些自定義控件,那就開始吧!
第一步:新建一個類名字爲NavFootView,然後繼承LinearLayout,要重寫至少兩個構造方法.

public class NavFootView extends LinearLayout {

    public NavFootView(Context context) {
        super(context);
    }
    public NavFootView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    public NavFootView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}

第二步:就是如何動態獲取該控件的寬高,和手指點擊該控件後的座標,爲什麼要這樣做呢?因爲我們只有獲取到控件的寬高,才能進行計算出每個圖標占多少的空間。

public class NavFootView extends LinearLayout {
    public NavFootView(Context context) {
        super(context);
    }
    public NavFootView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    public NavFootView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    //獲取觸摸的座標
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("data-->", "" + event.getX());
        Log.i("data-->", "" + event.getX());

        return super.onTouchEvent(event);
    }
    //獲取控件的寬高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //獲取控件的寬
        int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        //獲取控件的高
        int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
        Log.i("data-->", "寬:" + parentWidth);
        Log.i("data-->", "高:" + parentHeight);
        this.setMeasuredDimension(parentWidth, parentHeight);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

這個時候就可以獲取到控件的寬高和觸摸的座標。
第三步:嚮導航欄內動態添加數據
在做這個之前我們要先進行物理數據的儲備,因爲之後的操作需要根據這些數據,進行操作,比如導航欄點擊之後圖標變成什麼樣子,字體的顏色等。新建幾個方法採用java中的鏈式編程的方式.

//添加item
    public NavFootView addItem(String title, int icBefore, int icAfter) {
        return this;
    }
 //進行項目的創建--所有的操作放在這個地方
    public void build(){
       
    }
    //這個方法是上篇的一個方法就是用於動態生成
 private TextView getTextView(String title, int drawableId) {
        TextView textView = new TextView(context);
        textView.setText(title);
        //這一步就是讓字體居中
        textView.setGravity(Gravity.CENTER);
        //給TextView設置佈局參數--第一個參數是寬,第二個參數是高,第三個參數是相當於 android:layout_weight="1"
        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1.0f);
        textView.setLayoutParams(params);
        textView.setTextColor(Color.BLACK);
        Drawable drawable = getResources().getDrawable(drawableId);
        //這句話一定要寫
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
        // setCompoundDrawables(left ,top ,right, bottom);
        textView.setCompoundDrawables(null, drawable, null, null);
        return textView;
    }

下邊就是第三步整體的代碼:

public class NavFootView extends LinearLayout {
    public NavFootView(Context context) {
        super(context);
        this.context = context;
    }
    public NavFootView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }
    public NavFootView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
    }
    //點擊之前的圖標
    private Map<String, Integer> icBeforeMap = new HashMap<>();
    //點擊之後的圖標
    private Map<String, Integer> icAfterMap = new HashMap<>();
    //存儲標題
    private List<String> titleList = new ArrayList<>();
    //獲取控件的寬
    private int parentWidth;
    //獲取控件的高
    private int parentHeight;
    private Context context;
    //獲取觸摸的座標
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        return super.onTouchEvent(event);
    }
    //獲取控件的寬高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //獲取控件的寬
        parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        //獲取控件的高
        parentHeight = MeasureSpec.getSize(heightMeasureSpec);
        this.setMeasuredDimension(parentWidth, parentHeight);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    //添加item
    public NavFootView addItem(String title, int icBefore, int icAfter) {
        titleList.add(title);
        icBeforeMap.put(title, icBefore);
        icAfterMap.put(title, icAfter);
        return this;
    }
    //進行項目的創建--所有的操作放在這個地方
    public void build() {
        Iterator<String> iterator = titleList.iterator();
        while (iterator.hasNext()){
            String next = iterator.next();
            this.addView(getTextView(next,icBeforeMap.get(next)));
        }
    }
    //創建一個TextView
    private TextView getTextView(String title, int drawableId) {
        TextView textView = new TextView(context);
        textView.setText(title);
        //這一步就是讓字體居中
        textView.setGravity(Gravity.CENTER);
        //給TextView設置佈局參數--第一個參數是寬,第二個參數是高,第三個參數是相當於 android:layout_weight="1"
        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1.0f);
        textView.setLayoutParams(params);
        textView.setTextColor(Color.BLACK);
        Drawable drawable = getResources().getDrawable(drawableId);
        //這句話一定要寫
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
        // setCompoundDrawables(left ,top ,right, bottom);
        textView.setCompoundDrawables(null, drawable, null, null);
        return textView;
    }
}

那怎麼使用呢?請看下邊
首先就是在xml裏進行配置,本教程採用的是在xml裏配置的方式,也可以用代碼動態也可以,只是爲了方便而已.
xml中配置

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.listview.MainActivity">
  <com.listview.NavFootView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/container"
    android:orientation="horizontal">
  </com.listview.NavFootView>
</LinearLayout>

在代碼中使用

public class MainActivity extends AppCompatActivity {
    NavFootView container;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        container = findViewById(R.id.container);
        container.addItem("首頁", R.mipmap.ads1, R.mipmap.ads2);
        container.addItem("消息", R.mipmap.datav1, R.mipmap.datav2);
        container.addItem("聯繫人", R.mipmap.openad1, R.mipmap.openad2);
        container.addItem("我的", R.mipmap.re1, R.mipmap.re2);
        container.build();
    }
}

效果圖:
在這裏插入圖片描述
現在短短的幾行,就已經顯示出來了,但是這樣是不夠的,怎麼實現點擊之後圖標顏色變換呢?
第四步:如何改變點擊之後圖標的變換和字體顏色的變換?
這個時候就要用到第一步的那兩個方法了,一個是獲得觸摸的座標,一個是獲得控件寬高,那怎麼使用呢?這個時候新建一個方法

 //獲取點擊的是哪個
    public void selectPage(int index){

    }

如何使用呢?直接這樣使用就好了, int index = (int)(x/(parentWidth/titleList.size()));這個計算的理念是,導航欄平分之後,就只需要計算出觸摸的區域是在哪個區域就可以了

 //獲取觸摸的座標
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
       int index  = (int) (x/(parentWidth/titleList.size()));
        selectPage(index);
        return super.onTouchEvent(event);
    }

既然數據要添加完了,這個時候就是要獲取點擊的那個控件了.新建一個方法

    //給TextView設置圖片
    private void setTextViewDrawable(TextView textView, int drawableId) {
        Drawable drawable = getResources().getDrawable(drawableId);
        //這句話一定要寫
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
        // setCompoundDrawables(left ,top ,right, bottom);
        textView.setCompoundDrawables(null, drawable, null, null);
    }

這個時候selectPage這個方法就變成

 //獲取點擊的是哪個
    public void selectPage(int index) {
        //獲得控件總共的數量
        int childCount = this.getChildCount();
        for (int i = 0; i < childCount; i++) {
            TextView textView = (TextView) this.getChildAt(i);
            if (index == i) {
                //選中
                textView.setTextColor(Color.RED);
                setTextViewDrawable(textView,icAfterMap.get(textView.getText().toString().trim()));
            } else {
                //未選中
                textView.setTextColor(Color.BLACK);
                setTextViewDrawable(textView,icBeforeMap.get(textView.getText().toString().trim()));
            }
        }
    }

整體代碼:

public class NavFootView extends LinearLayout {
    public NavFootView(Context context) {
        super(context);
        this.context = context;
    }
    public NavFootView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }
    public NavFootView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
    }
    //點擊之前的圖標
    private Map<String, Integer> icBeforeMap = new HashMap<>();
    //點擊之後的圖標
    private Map<String, Integer> icAfterMap = new HashMap<>();
    //存儲標題
    private List<String> titleList = new ArrayList<>();
    //獲取控件的寬
    private int parentWidth;
    //獲取控件的高
    private int parentHeight;
    private Context context;
    //獲取觸摸的座標
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        int index = (int) (x / (parentWidth / titleList.size()));
        selectPage(index);
        return super.onTouchEvent(event);
    }
    //獲取控件的寬高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //獲取控件的寬
        parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        //獲取控件的高
        parentHeight = MeasureSpec.getSize(heightMeasureSpec);
        this.setMeasuredDimension(parentWidth, parentHeight);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    //添加item
    public NavFootView addItem(String title, int icBefore, int icAfter) {
        titleList.add(title);
        icBeforeMap.put(title, icBefore);
        icAfterMap.put(title, icAfter);
        return this;
    }
    //進行項目的創建--所有的操作放在這個地方
    public void build() {
        Iterator<String> iterator = titleList.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            this.addView(getTextView(next, icBeforeMap.get(next)));
        }
    }
    //獲取點擊的是哪個
    public void selectPage(int index) {
        //獲得控件總共的數量
        int childCount = this.getChildCount();
        for (int i = 0; i < childCount; i++) {
            TextView textView = (TextView) this.getChildAt(i);
            if (index == i) {
                //選中
                textView.setTextColor(Color.RED);
                setTextViewDrawable(textView,icAfterMap.get(textView.getText().toString().trim()));
            } else {
                //未選中
                textView.setTextColor(Color.BLACK);
                setTextViewDrawable(textView,icBeforeMap.get(textView.getText().toString().trim()));
            }
        }
    }
    //創建一個TextView
    private TextView getTextView(String title, int drawableId) {
        TextView textView = new TextView(context);
        textView.setText(title);
        //這一步就是讓字體居中
        textView.setGravity(Gravity.CENTER);
        //給TextView設置佈局參數--第一個參數是寬,第二個參數是高,第三個參數是相當於 android:layout_weight="1"
        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT,
            1.0f);
        textView.setLayoutParams(params);
        textView.setTextColor(Color.BLACK);
        Drawable drawable = getResources().getDrawable(drawableId);
        //這句話一定要寫
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
        // setCompoundDrawables(left ,top ,right, bottom);
        textView.setCompoundDrawables(null, drawable, null, null);
        return textView;
    }
    //給TextView設置圖片
    private void setTextViewDrawable(TextView textView, int drawableId) {
        Drawable drawable = getResources().getDrawable(drawableId);
        //這句話一定要寫
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
        // setCompoundDrawables(left ,top ,right, bottom);
        textView.setCompoundDrawables(null, drawable, null, null);
    }
}

效果如下:
在這裏插入圖片描述
是不是越來越完善了呢,對的現在已經完成了一大步了。
第五步:也是最重要的一步了,導航欄的作用是什麼,大家都知道是用於用戶單擊跳轉到其他頁面的,導航欄一般在Fragment和Activity中都會使用,那首先就是如何才能在Fragment使用呢?
首先就是修改activity的xml文件,加入幀佈局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.listview.MainActivity"
  android:orientation="vertical">
  <FrameLayout
    android:id="@+id/frameLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1">
  </FrameLayout>
  <com.listview.NavFootView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/container"
    android:orientation="horizontal">
  </com.listview.NavFootView>
</LinearLayout>

然後就是修改之前的一個方法,就是添加數據的那個方法,加入能夠添加Fragment的功能,就是多了一個物理資源的儲備.

   //添加item
    public NavFootView addItem(String title, int icBefore, int icAfter, Fragment fragment) {
        titleList.add(title);
        icBeforeMap.put(title, icBefore);
        icAfterMap.put(title, icAfter);
        fragmentMap.put(title, fragment);
        return this;
    }

再新建處理跳轉的方法和設置Fragment佈局id的方法

    //跳轉頁面
    private void switchFragment(String title) {

    }
     public void setFrameLayoutId(int frameLayoutId){
        this.frameLayoutId = frameLayoutId;
    }

處理跳轉的方法:

  private Fragment currentFragment = null;
    //跳轉頁面
    private void switchFragment(String title) {
        Fragment fragment = fragmentMap.get(title);
        //開啓事務
        FragmentTransaction fragmentTransaction = ((Activity) context).getFragmentManager()
            .beginTransaction();
        if (fragment.isAdded()) {
            if (currentFragment != null) {
                fragmentTransaction.hide(currentFragment).show(fragment);
            } else {
                fragmentTransaction.show(fragment);
            }
        } else {
            if (currentFragment != null) {
                fragmentTransaction.hide(currentFragment).add(frameLayoutId, fragment);
            } else {
                fragmentTransaction.add(frameLayoutId, fragment);
            }
        }
        currentFragment = fragment;
        fragmentTransaction.commit();
    }

好了到這裏,如果僅僅是使用,現在已經可以使用了,現在先貼出全部的代碼:
首先貼出導航欄的代碼

public class NavFootView extends LinearLayout {
    public NavFootView(Context context) {
        super(context);
        this.context = context;
    }
    public NavFootView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }
    public NavFootView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
    }
    //點擊之前的圖標
    private Map<String, Integer> icBeforeMap = new HashMap<>();
    //點擊之後的圖標
    private Map<String, Integer> icAfterMap = new HashMap<>();
    //存儲標題
    private List<String> titleList = new ArrayList<>();
    //獲取控件的寬
    private int parentWidth;
    //獲取控件的高
    private int parentHeight;
    //存儲Fragment
    private Map<String, Fragment> fragmentMap = new HashMap<>();
    private Context context;
    //佈局id
    private int frameLayoutId;
    //獲取觸摸的座標
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        int index = (int) (x / (parentWidth / titleList.size()));
        selectPage(index);
        return super.onTouchEvent(event);
    }
    //獲取控件的寬高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //獲取控件的寬
        parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        //獲取控件的高
        parentHeight = MeasureSpec.getSize(heightMeasureSpec);
        this.setMeasuredDimension(parentWidth, parentHeight);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    //添加item
    public NavFootView addItem(String title, int icBefore, int icAfter, Fragment fragment) {
        titleList.add(title);
        icBeforeMap.put(title, icBefore);
        icAfterMap.put(title, icAfter);
        fragmentMap.put(title, fragment);
        return this;
    }
    //進行項目的創建--所有的操作放在這個地方
    public void build() {
        Iterator<String> iterator = titleList.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            this.addView(getTextView(next, icBeforeMap.get(next)));
        }
    }
    //獲取點擊的是哪個
    public void selectPage(int index) {
        //獲得控件總共的數量
        int childCount = this.getChildCount();
        for (int i = 0; i < childCount; i++) {
            TextView textView = (TextView) this.getChildAt(i);
            String title = textView.getText().toString().trim();
            if (index == i) {
                //選中
                textView.setTextColor(Color.RED);
                setTextViewDrawable(textView, icAfterMap.get(title));
                switchFragment(title);
            } else {
                //未選中
                textView.setTextColor(Color.BLACK);
                setTextViewDrawable(textView, icBeforeMap.get(title));
            }
        }
    }
    //設置佈局id
    public void setFrameLayoutId(int frameLayoutId) {
        this.frameLayoutId = frameLayoutId;
    }
    private Fragment currentFragment = null;
    //跳轉頁面
    private void switchFragment(String title) {
        Fragment fragment = fragmentMap.get(title);
        //開啓事務
        FragmentTransaction fragmentTransaction = ((Activity) context).getFragmentManager()
            .beginTransaction();
        if (fragment.isAdded()) {
            if (currentFragment != null) {
                fragmentTransaction.hide(currentFragment).show(fragment);
            } else {
                fragmentTransaction.show(fragment);
            }
        } else {
            if (currentFragment != null) {
                fragmentTransaction.hide(currentFragment).add(frameLayoutId, fragment);
            } else {
                fragmentTransaction.add(frameLayoutId, fragment);
            }
        }
        currentFragment = fragment;
        fragmentTransaction.commit();
    }
    //創建一個TextView
    private TextView getTextView(String title, int drawableId) {
        TextView textView = new TextView(context);
        textView.setText(title);
        //這一步就是讓字體居中
        textView.setGravity(Gravity.CENTER);
        //給TextView設置佈局參數--第一個參數是寬,第二個參數是高,第三個參數是相當於 android:layout_weight="1"
        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT,
            1.0f);
        textView.setLayoutParams(params);
        textView.setTextColor(Color.BLACK);
        Drawable drawable = getResources().getDrawable(drawableId);
        //這句話一定要寫
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
        // setCompoundDrawables(left ,top ,right, bottom);
        textView.setCompoundDrawables(null, drawable, null, null);
        return textView;
    }

    //給TextView設置圖片
    private void setTextViewDrawable(TextView textView, int drawableId) {
        Drawable drawable = getResources().getDrawable(drawableId);
        //這句話一定要寫
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
        // setCompoundDrawables(left ,top ,right, bottom);
        textView.setCompoundDrawables(null, drawable, null, null);
    }
}

再貼出使用過程的代碼:

public class MainActivity extends AppCompatActivity {
    NavFootView container;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        container = findViewById(R.id.container);
        container.setFrameLayoutId(R.id.fl_container);
        container.addItem("首頁", R.mipmap.ads1, R.mipmap.ads2, new HomeFragment());
        container.addItem("消息", R.mipmap.datav1, R.mipmap.datav2, new Home2Fragment());
        container.addItem("聯繫人", R.mipmap.openad1, R.mipmap.openad2, new Home3Fragment());
        container.addItem("我的", R.mipmap.re1, R.mipmap.re2, new Home4Fragment());
        container.build();
    }
}

效果圖:
在這裏插入圖片描述
看到這麼短短几行的代碼就完成了,動態導航欄的功能,還能實現跳轉是不是感覺很驚喜,對就是這麼簡單,相信大家在一步一步的過程也能學到一些東西。下邊就是對這個導航欄的加強,如果有興趣的話,那就跟我繼續奮鬥吧。
第六步:設置默認頁面,相信很多小夥伴都知道,比如首頁,打開就會自動跳轉到首頁.
新建一個方法

    //設置默認跳轉頁面
    public void setDefaultIndex(int defaultIndex) {
        this.defaultIndex = defaultIndex;
    }

重寫build(),簡單的一句就實現了默認跳轉

 //進行項目的創建--所有的操作放在這個地方
    public void build() {
        Iterator<String> iterator = titleList.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            this.addView(getTextView(next, icBeforeMap.get(next)));
        }
        if (defaultIndex != -1) {
            selectPage(defaultIndex);
        }
    }

第七步:之前的fragment的跳轉已經完成了,那關於Activity的跳轉呢?
之後再更新,好累了,一口氣完成這麼多,下次再完善,代碼,大家也可以自行進行修改,還有就是一些小夥伴,會在這裏報錯,大家注意Fragment有兩個版本,所以大家按需求導入特定的包,使用也會有一些區別,就不一一介紹了,遇到問題自己百度解決吧!
//跳轉頁面
private void switchFragment(String title) {
Fragment fragment = fragmentMap.get(title);
//開啓事務
FragmentTransaction fragmentTransaction = ((Activity) context).getFragmentManager()
.beginTransaction();
if (fragment.isAdded()) {
if (currentFragment != null) {
fragmentTransaction.hide(currentFragment).show(fragment);
} else {
fragmentTransaction.show(fragment);
}
} else {
if (currentFragment != null) {
fragmentTransaction.hide(currentFragment).add(frameLayoutId, fragment);
} else {
fragmentTransaction.add(frameLayoutId, fragment);
}
}
currentFragment = fragment;
fragmentTransaction.commit();
}`
下邊粘貼處全部的代碼,分享給大家

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class NavFootView extends LinearLayout {

    public NavFootView(Context context) {
        super(context);
        this.context = context;
    }

    public NavFootView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    public NavFootView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
    }

    //點擊之前的圖標
    private Map<String, Integer> icBeforeMap = new HashMap<>();
    //點擊之後的圖標
    private Map<String, Integer> icAfterMap = new HashMap<>();
    //存儲標題
    private List<String> titleList = new ArrayList<>();
    //獲取控件的寬
    private int parentWidth;
    //獲取控件的高
    private int parentHeight;
    //存儲Fragment
    private Map<String, Fragment> fragmentMap = new HashMap<>();
    private Context context;
    //佈局id
    private int frameLayoutId;
    //默認跳轉的頁面
    private int defaultIndex = -1;
    //碎片處理
    private Fragment currentFragment = null;

    //獲取觸摸的座標
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        int index = (int) (x / (parentWidth / titleList.size()));
        selectPage(index);
        return super.onTouchEvent(event);
    }

    //獲取控件的寬高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //獲取控件的寬
        parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        //獲取控件的高
        parentHeight = MeasureSpec.getSize(heightMeasureSpec);
        this.setMeasuredDimension(parentWidth, parentHeight);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    //添加item
    public NavFootView addItem(String title, int icBefore, int icAfter, Fragment fragment) {
        titleList.add(title);
        icBeforeMap.put(title, icBefore);
        icAfterMap.put(title, icAfter);
        fragmentMap.put(title, fragment);
        return this;
    }

    //進行項目的創建--所有的操作放在這個地方
    public void build() {
        Iterator<String> iterator = titleList.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            this.addView(getTextView(next, icBeforeMap.get(next)));
        }
        if (defaultIndex != -1) {
            selectPage(defaultIndex);
        }
    }

    //獲取點擊的是哪個
    public void selectPage(int index) {
        //獲得控件總共的數量
        int childCount = this.getChildCount();
        for (int i = 0; i < childCount; i++) {
            TextView textView = (TextView) this.getChildAt(i);
            String title = textView.getText().toString().trim();
            if (index == i) {
                //選中
                textView.setTextColor(Color.RED);
                setTextViewDrawable(textView, icAfterMap.get(title));
                switchFragment(title);
            } else {
                //未選中
                textView.setTextColor(Color.BLACK);
                setTextViewDrawable(textView, icBeforeMap.get(title));
            }
        }
    }

    //設置佈局id
    public void setFrameLayoutId(int frameLayoutId) {
        this.frameLayoutId = frameLayoutId;
    }

    //設置默認跳轉頁面
    public void setDefaultIndex(int defaultIndex) {
        this.defaultIndex = defaultIndex;
    }

    //跳轉頁面
    private void switchFragment(String title) {
        Fragment fragment = fragmentMap.get(title);
        //開啓事務
        FragmentTransaction fragmentTransaction = ((Activity) context).getFragmentManager()
            .beginTransaction();
        if (fragment.isAdded()) {
            if (currentFragment != null) {
                fragmentTransaction.hide(currentFragment).show(fragment);
            } else {
                fragmentTransaction.show(fragment);
            }
        } else {
            if (currentFragment != null) {
                fragmentTransaction.hide(currentFragment).add(frameLayoutId, fragment);
            } else {
                fragmentTransaction.add(frameLayoutId, fragment);
            }
        }
        currentFragment = fragment;
        fragmentTransaction.commit();
    }

    //創建一個TextView
    private TextView getTextView(String title, int drawableId) {
        TextView textView = new TextView(context);
        textView.setText(title);
        //這一步就是讓字體居中
        textView.setGravity(Gravity.CENTER);
        //給TextView設置佈局參數--第一個參數是寬,第二個參數是高,第三個參數是相當於 android:layout_weight="1"
        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT,
            1.0f);
        textView.setLayoutParams(params);
        textView.setTextColor(Color.BLACK);
        Drawable drawable = getResources().getDrawable(drawableId);
        //這句話一定要寫
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
        // setCompoundDrawables(left ,top ,right, bottom);
        textView.setCompoundDrawables(null, drawable, null, null);
        return textView;
    }

    //給TextView設置圖片
    private void setTextViewDrawable(TextView textView, int drawableId) {
        Drawable drawable = getResources().getDrawable(drawableId);
        //這句話一定要寫
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
        // setCompoundDrawables(left ,top ,right, bottom);
        textView.setCompoundDrawables(null, drawable, null, null);
    }

}

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    NavFootView container;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        container = findViewById(R.id.container);
        container.setFrameLayoutId(R.id.fl_container);
        container.setDefaultIndex(0);
        container.addItem("首頁", R.mipmap.ads1, R.mipmap.ads2, new HomeFragment());
        container.addItem("消息", R.mipmap.datav1, R.mipmap.datav2, new Home2Fragment());
        container.addItem("聯繫人", R.mipmap.openad1, R.mipmap.openad2, new Home3Fragment());
        container.addItem("我的", R.mipmap.re1, R.mipmap.re2, new Home4Fragment());
        container.build();
    }
}

簡單方便的動態導航欄就完成了,謝謝大家支持,後續會跟大家分享更多的東西.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章