底部切換欄使用FragmentTabHost+Fragment實(shí)現(xiàn),很早以前寫過一篇,這篇算是整合下使用
首先來看下效果

效果.gif
使用如下
List<BarTab> list;
BarTab tab;
Bundle bundle;
list = new ArrayList<>();
tab = new BarTab();
tab.setTitle("首頁(yè)");
tab.setCls(TestFragment.class);
tab.setImageNormal(R.mipmap.home1);
tab.setImageSelect(R.mipmap.home2);
bundle = new Bundle();
bundle.putString("title","首頁(yè)");
tab.setBundle(bundle);
list.add(tab);
tab = new BarTab();
tab.setTitle("發(fā)現(xiàn)");
tab.setCls(TestFragment.class);
tab.setImageNormal(R.mipmap.glod1);
tab.setImageSelect(R.mipmap.glod2);
bundle = new Bundle();
bundle.putString("title","發(fā)現(xiàn)");
tab.setBundle(bundle);
list.add(tab);
tab = new BarTab();
tab.setTitle("用戶");
tab.setCls(TestFragment.class);
tab.setImageNormal(R.mipmap.user1);
tab.setImageSelect(R.mipmap.user2);
bundle = new Bundle();
bundle.putString("title","用戶");
tab.setBundle(bundle);
list.add(tab);
BaseBottomBar<BarTab> bottomBar = new BaseBottomBar<BarTab>(mActivity,
tabHost,R.id.fl_test,R.layout.item_bar,list) {
@Override
protected TextView getBarText(View view) {
return (TextView) view.findViewById(R.id.tv_bar);
}
@Override
protected ImageView getBarImage(View view) {
return (ImageView) view.findViewById(R.id.iv_bar);
}
@Override
protected int setSelectColor() {
return ContextCompat.getColor(mContext,R.color.appMainColor);
}
};
bottomBar.setImageLoader(new ImageLoader() {
@Override
public void ImageLoader(Context context, Object o, ImageView view) {
Glide.with(context).load(o).into(view);
}
}).create();
就是創(chuàng)建一個(gè)BaseBottomBar對(duì)象設(shè)置他的布局id和底部欄布局以及數(shù)據(jù)list就可以了!
必須實(shí)現(xiàn)的2個(gè)方法是getBarText和getBarImage,用來設(shè)置點(diǎn)擊之后圖片和文字的變化
當(dāng)使用create()方法就可以創(chuàng)建成功。
代碼只有3個(gè)類

代碼層
首先看下FragmentTabHost的基本使用
谷歌官方例子
Activity中使用
import com.example.android.supportv4.R;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTabHost;
/**
* This demonstrates how you can implement switching between the tabs of a
* TabHost through fragments, using FragmentTabHost.
*/
public class FragmentTabs extends FragmentActivity {
private FragmentTabHost mTabHost;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_tabs);
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Simple"),
FragmentStackSupport.CountingFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("Contacts"),
LoaderCursorSupport.CursorLoaderListFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("custom").setIndicator("Custom"),
LoaderCustomSupport.AppListFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("throttle").setIndicator("Throttle"),
LoaderThrottleSupport.ThrottledLoaderListFragment.class, null);
}
}
Fragment中使用
import com.example.android.supportv4.R;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTabHost;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentTabsFragmentSupport extends Fragment {
private FragmentTabHost mTabHost;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mTabHost = new FragmentTabHost(getActivity());
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.fragment1);
mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Simple"),
FragmentStackSupport.CountingFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("Contacts"),
LoaderCursorSupport.CursorLoaderListFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("custom").setIndicator("Custom"),
LoaderCustomSupport.AppListFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("throttle").setIndicator("Throttle"),
LoaderThrottleSupport.ThrottledLoaderListFragment.class, null);
return mTabHost;
}
@Override
public void onDestroyView() {
super.onDestroyView();
mTabHost = null;
}
}
以上是來自網(wǎng)上搜索的
基本使用有了,就開始寫一個(gè)管理方法,用來簡(jiǎn)單使用吧!
首先我們先設(shè)置主布局
activity_test.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"
android:orientation="vertical"
tools:context="com.gjn.msdemo.homepage.TestActivity">
<FrameLayout
android:id="@+id/fl_test"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<android.support.v4.app.FragmentTabHost
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:id="@+id/fth_test" >
</android.support.v4.app.FragmentTabHost>
</LinearLayout>
然后我們?cè)谠O(shè)置一個(gè)每項(xiàng)的底部菜單
我這邊設(shè)置了一個(gè)常規(guī)的一張圖片和一個(gè)標(biāo)題

底部Item
item_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_bar"
android:layout_width="wrap_content"
android:layout_height="30dp"
app:srcCompat="@mipmap/home2" />
<TextView
android:id="@+id/tv_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="首頁(yè)" />
</LinearLayout>
之后我們就要定義Item的屬性了
這邊我定義了一個(gè)屬性類
BarTab.java
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/**
* BarTab
* Author: gjn.
* Time: 2018/1/4.
*/
public class BarTab {
//標(biāo)題
private String title;
//綁定的Fragment
private Class<?> cls;
//整個(gè)底部View
private View view;
//Bundle
private Bundle bundle;
//圖標(biāo)正常情況
private Object imageNormal;
//圖標(biāo)選中情況
private Object imageSelect;
//底部菜單的2個(gè)布局view
private ItemView itemView;
public static class ItemView{
private ImageView image;
private TextView text;
public ImageView getImage() {
return image;
}
public void setImage(ImageView image) {
this.image = image;
}
public TextView getText() {
return text;
}
public void setText(TextView text) {
this.text = text;
}
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Class<?> getCls() {
return cls;
}
public void setCls(Class<?> cls) {
this.cls = cls;
}
public Bundle getBundle() {
return bundle;
}
public void setBundle(Bundle bundle) {
this.bundle = bundle;
}
public View getView() {
return view;
}
public void setView(View view) {
this.view = view;
}
public Object getImageNormal() {
return imageNormal;
}
public void setImageNormal(Object imageNormal) {
this.imageNormal = imageNormal;
}
public Object getImageSelect() {
return imageSelect;
}
public void setImageSelect(Object imageSelect) {
this.imageSelect = imageSelect;
}
public ItemView getItemView() {
return itemView;
}
public void setItemView(ItemView itemView) {
this.itemView = itemView;
}
}
我們對(duì)每一個(gè)底部選項(xiàng)都進(jìn)行屬性設(shè)置
最后我們寫一個(gè)管理工具
BaseBottomBar.java
import android.app.Activity;
import android.graphics.Color;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTabHost;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TabHost;
import android.widget.TabWidget;
import android.widget.TextView;
import com.gjn.utilslibrary.utils.ImageLoader;
import java.util.ArrayList;
import java.util.List;
/**
* BaseBottomBar
* Author: gjn.
* Time: 2018/1/4.
*/
public abstract class BaseBottomBar<T extends BarTab> implements TabHost.OnTabChangeListener {
private Activity mActivity;
private FragmentTabHost mTabHost;
private int mContainerId;
private int mViewId;
private List<?> mItems;
private int mNormalColor = -1;
private int mSelectColor = -1;
private BottomBarListener bottomBarListener;
private ImageLoader mImageLoader;
public BaseBottomBar(Activity activity, FragmentTabHost tabHost,
int containerId, int viewid, List<T> items) {
mActivity = activity;
mTabHost = tabHost;
mContainerId = containerId;
mViewId = viewid;
mItems = items == null ? new ArrayList<>() : items;
mNormalColor = setNormalColor();
mSelectColor = setSelectColor();
}
protected int setSelectColor() {
return Color.BLACK;
}
protected int setNormalColor() {
return Color.BLACK;
}
private void reset(T item) {
mImageLoader.ImageLoader(mActivity, item.getImageNormal(), getImage(item));
getText(item).setText(item.getTitle());
getText(item).setTextColor(mNormalColor);
}
private void select(T item) {
mImageLoader.ImageLoader(mActivity, item.getImageSelect(), getImage(item));
getText(item).setText(item.getTitle());
getText(item).setTextColor(mSelectColor);
}
private ImageView getImage(T item) {
return item.getItemView().getImage();
}
private TextView getText(T item) {
return item.getItemView().getText();
}
public BaseBottomBar setBottomBarListener(BottomBarListener bottomBarListener) {
this.bottomBarListener = bottomBarListener;
return this;
}
public void setCurrentTab(int i) {
mTabHost.setCurrentTab(i);
}
public List<?> getAllItem() {
return mItems;
}
public View getView(int i) {
T item = (T) mItems.get(i);
return item.getView();
}
public BarTab.ItemView getItemView(int i) {
T item = (T) mItems.get(i);
return item.getItemView();
}
public BaseBottomBar setImageLoader(ImageLoader imageLoader) {
mImageLoader = imageLoader;
return this;
}
public void setItems(List<?> items) {
mItems = items;
mTabHost.removeAllViews();
create();
}
public void create() {
if (mTabHost == null) {
throw new NullPointerException("TabHost is null!");
}
if (mImageLoader == null) {
throw new NullPointerException("ImageLoader is null.");
}
mTabHost.setup(mActivity, ((FragmentActivity) mActivity).getSupportFragmentManager(),
mContainerId);
mTabHost.setOnTabChangedListener(this);
mTabHost.getTabWidget().setDividerDrawable(null);
for (int i = 0; i < mItems.size(); i++) {
T item = (T) mItems.get(i);
//設(shè)置每個(gè)Item的view和內(nèi)部布局
View view = LayoutInflater.from(mActivity).inflate(mViewId, null, false);
BarTab.ItemView itemView = new BarTab.ItemView();
itemView.setImage(getBarImage(view));
itemView.setText(getBarText(view));
item.setView(view);
item.setItemView(itemView);
//未設(shè)置選中圖片,默認(rèn)為正常
if (item.getImageSelect() == null) {
item.setImageSelect(item.getImageNormal());
}
//設(shè)置默認(rèn)圖片
if (i == 0) {
select(item);
} else {
reset(item);
}
TabHost.TabSpec tabSpec = mTabHost.newTabSpec(item.getTitle()).setIndicator(view);
mTabHost.addTab(tabSpec, item.getCls(), item.getBundle());
}
}
@Override
public void onTabChanged(String tabId) {
TabWidget widget = mTabHost.getTabWidget();
for (int i = 0; i < widget.getChildCount(); i++) {
T item = (T) mItems.get(i);
if (i == mTabHost.getCurrentTab()) {
select(item);
if (bottomBarListener != null) {
bottomBarListener.onClick(i, tabId);
}
} else {
reset(item);
}
}
}
public interface BottomBarListener {
void onClick(int i, String title);
}
protected abstract TextView getBarText(View view);
protected abstract ImageView getBarImage(View view);
}
里面的ImageLoader只是一個(gè)簡(jiǎn)單的接口,用來使用Glide設(shè)置圖片的
ImageLoader.java
import android.content.Context;
import android.widget.ImageView;
/**
* ImageLoader
* Author: gjn.
* Time: 2018/1/2.
*/
public interface ImageLoader {
void ImageLoader(Context context, Object o, ImageView view);
}
總結(jié)
對(duì)以前的底部欄實(shí)現(xiàn)算是重新寫下。將方法整合下,可能還是比較繁瑣,不過目前算是我能實(shí)現(xiàn)的寫法整合了。