[AS2.3.3]底部栏实现 (使用FragmentTabHost+Fragment实现)

底部切换栏使用FragmentTabHost+Fragment实现,很早以前写过一篇,这篇算是整合下使用


首先来看下效果
效果.gif
使用如下

        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
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);
}

总结

对以前的底部栏实现算是重新写下。将方法整合下,可能还是比较繁琐,不过目前算是我能实现的写法整合了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值