底部切换栏使用FragmentTabHost+Fragment实现,很早以前写过一篇,这篇算是整合下使用
首先来看下效果
使用如下
List<BarTab> list;
BarTab tab;
Bundle bundle;
list = new ArrayList<>();
tab = new BarTab();
tab.setTitle("首页");
tab.setCls(TestFragment.class);
tab.setImageNormal(R.mipmap.home1);
tab.setImageSelect(R.mipmap.home2);
bundle = new Bundle();
bundle.putString("title","首页");
tab.setBundle(bundle);
list.add(tab);
tab = new BarTab();
tab.setTitle("发现");
tab.setCls(TestFragment.class);
tab.setImageNormal(R.mipmap.glod1);
tab.setImageSelect(R.mipmap.glod2);
bundle = new Bundle();
bundle.putString("title","发现");
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();
就是创建一个BaseBottomBar对象设置他的布局id和底部栏布局以及数据list就可以了!
必须实现的2个方法是getBarText和getBarImage,用来设置点击之后图片和文字的变化
当使用create()方法就可以创建成功。
代码只有3个类
首先看下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;
}
}
以上是来自网上搜索的
基本使用有了,就开始写一个管理方法,用来简单使用吧!
首先我们先设置主布局
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>
然后我们在设置一个每项的底部菜单
我这边设置了一个常规的一张图片和一个标题
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="首页" />
</LinearLayout>
之后我们就要定义Item的属性了
这边我定义了一个属性类
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 {
//标题
private String title;
//绑定的Fragment
private Class<?> cls;
//整个底部View
private View view;
//Bundle
private Bundle bundle;
//图标正常情况
private Object imageNormal;
//图标选中情况
private Object imageSelect;
//底部菜单的2个布局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;
}
}
我们对每一个底部选项都进行属性设置
最后我们写一个管理工具
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);
//设置每个Item的view和内部布局
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);
//未设置选中图片,默认为正常
if (item.getImageSelect() == null) {
item.setImageSelect(item.getImageNormal());
}
//设置默认图片
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只是一个简单的接口,用来使用Glide设置图片的
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);
}
总结
对以前的底部栏实现算是重新写下。将方法整合下,可能还是比较繁琐,不过目前算是我能实现的写法整合了。