动态多变的tab菜单底部

版权声明:本文为博主原创文章,未经博主允许不得转载。

最近在做几个外包项目,由于需求的变动性与项目的时间要求结限比较短,所以有时,特别烦,写好的要反反复复的,修改好多次,为了以后的灵活使用,所以就必须要动态的改变底部菜单,从而灵活的处理各自的需求。所以这是需求,也是最基础的吧。

先来看一看,它的效果。

这里写图片描述 三个
这里写图片描述 五个

我想只要有足够多的空间,一定是可以满足我现在的需求的,以后在逐渐的完善它把,可以让他滑动。

这个tab的实现,是使用的自定义的LinearLayout,先来看一看他吧。

/**
 * Created by zhang on 2016/11/18.
 * <p>
 * 自定义tab底部菜单
 */
public class TabLinearLayoutTwo extends LinearLayout {
    //底部tab动画
    private AnimatorSet animator1;
    private AnimatorSet animator2;
    private AnimatorSet animator3;
    private AnimatorSet animator4;
    //底部菜单的图片数组
    private int[] mDrawableIds = new int[]{
            R.drawable.tab_events, R.drawable.tab_events, R.drawable.tab_message
    };
    //底部菜单的动画数组
    private AnimatorSet[] mAnimatorSetList = new AnimatorSet[]{
            animator1, animator2, animator3, animator4, animator4
    };
    // 底部菜单的文字数组
    private CharSequence[] mLabels = {"首页", " 个人中心", "服务"};

    // 存放底部菜单图片CheckedTextView的集合
    private List<CheckedTextView> mCheckedList = new ArrayList<CheckedTextView>();
    // 存放底部菜单文字TextView的集合
    private List<TextView> mCheckedTextList = new ArrayList<TextView>();

    // 存放底部菜单每一项的View的集合,如:首页 、个人中心两个底部
    private List<View> mViewList = new ArrayList<View>();


    // 存放图片上面小红点的集合
    private List<TextView> mRedIndicate = new ArrayList<TextView>();

    public TabLinearLayoutTwo(Context context) {
        super(context);
        init(context); // 初始化控件

    }


    public TabLinearLayoutTwo(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context); // 初始化控件

    }

    public TabLinearLayoutTwo(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context); // 初始化控件

    }

    private void init(Context context) {
        this.setOrientation(LinearLayout.HORIZONTAL);//设置lin为水平方向
        LayoutInflater inflater = LayoutInflater.from(context);//inflater加载布局
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        params.weight = 1.0f;//居中权重
        params.gravity = Gravity.CENTER_VERTICAL;
        int size = mLabels.length;//将文字数据的大小赋值给size
        //循环添加每个tab
        for (int i = 0; i < size; i++) {
            final int index = i;
            final View view = inflater.inflate(R.layout.tablin_item_two, null);
            final CheckedTextView itemName = (CheckedTextView) view.findViewById(R.id.item_name_iv);
            //初始化动画
            if (index == 0) {//tab一动画
                mAnimatorSetList[0] = (AnimatorSet) AnimatorInflater.loadAnimator(context, R.animator.anim_out);
            } else if (index == 1) {//tab二动画
                mAnimatorSetList[1] = (AnimatorSet) AnimatorInflater.loadAnimator(context, R.animator.anim_out);
            } else if (index == 2) {//tab三动画
                mAnimatorSetList[2] = (AnimatorSet) AnimatorInflater.loadAnimator(context, R.animator.anim_out);
            } else if (index == 3) {//tab四动画
                mAnimatorSetList[3] = (AnimatorSet) AnimatorInflater.loadAnimator(context, R.animator.anim_out);
            } else {//其他tab动画
                mAnimatorSetList[i] = (AnimatorSet) AnimatorInflater.loadAnimator(context, R.animator.anim_out);
            }
            //设置CheckedTextView的图片
            itemName.setCompoundDrawablesRelativeWithIntrinsicBounds(null,
                    context.getResources().getDrawable(mDrawableIds[i]), null, null);
            //设置textview的文字
            final TextView itemText = (TextView) view.findViewById(R.id.item_text);
            itemText.setText(mLabels[i]);
            //图片头上小红点
            final TextView indicateTv = (TextView) view.findViewById(R.id.item_indicate);
            this.addView(view, params);
            itemName.setTag(index);//为CheckedTextView设置tag,为的是后面的区分与切换
            //设置tab动画
            if (itemName != null) {
                mAnimatorSetList[i].setTarget(itemName);
            }
            //存对应的view数据
            mCheckedList.add(itemName);//CheckedTextView
            mCheckedTextList.add(itemText);//菜单文字
            mRedIndicate.add(indicateTv);//小红点
            mViewList.add(view);//一个底部 (如首页)
            //给每个tab设置点击事件
            view.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    setTabLinearViewCheack(index);
                    if (null != mTabListener) {
                        // tab切换监听
                        mTabListener.onTabSelected(index, true);
                    }
                }
            });
            //初始化底部菜单tab的选中,默认让第一个选中
            if (i == 0) {
                //选中与字体颜色
                itemName.setChecked(true);
                itemText.setTextColor(ContextCompat.getColor(getContext(), R.color.colorAccent));

            } else {
                itemName.setChecked(false);
                itemText.setTextColor(ContextCompat.getColor(getContext(), R.color.colorbule));
            }


        }
    }


    /**
     * tabLinearLayout提供的设置tab选中的方法
     *
     * @param index
     */
    public void setTabLinearViewCheack(int index) {
        int size = mCheckedList.size();
        for (int i = 0; i < size; i++) {
            //遍历集合,设置选中
            CheckedTextView itemButton = mCheckedList.get(i);
            TextView itemText = mCheckedTextList.get(i);
            if ((Integer) itemButton.getTag() == index) {
                itemButton.setChecked(true);
                itemText.setTextColor(ContextCompat.getColor(getContext(), R.color.colorAccent));
                mAnimatorSetList[i].start();
                Log.i("tab", mLabels[index] + "tab被选中!!!");

            } else {
                itemButton.setChecked(false);
                itemText.setTextColor(ContextCompat.getColor(getContext(), R.color.colorbule));
            }
        }

    }

    /**
     * tabLinearLayout提供的设置小红点显示的方法
     *
     * @param context    上下文
     * @param showNumber 设置显示数量
     * @param visible    是否显示,如果false,则都不显示
     */
    public void setRedIndicateViewDisplay(Context context, int tabPosition, String showNumber, boolean visible) {
        int size = mRedIndicate.size();
        TextView indicateTv = mRedIndicate.get(tabPosition);
        indicateTv.setVisibility(visible ? View.VISIBLE : View.GONE);
        indicateTv.setText(showNumber);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthSpecMode != MeasureSpec.EXACTLY) {
            widthSpecSize = 0;
        }
        if (heightSpecMode != MeasureSpec.EXACTLY) {
            heightSpecSize = 0;
        }
        if (widthSpecMode == MeasureSpec.UNSPECIFIED || heightSpecMode == MeasureSpec.UNSPECIFIED) {
        }
        // 控件的最大高度,就是下边tab的背景最大高度
        int width;
        int height;
        width = Math.max(getMeasuredWidth(), widthSpecSize);
        height = Math.max(this.getBackground().getIntrinsicHeight(), heightSpecSize);
        setMeasuredDimension(width, height);
    }

    /**
     * tab选中的监听回调
     */

    private OnTabSelectedListener mTabListener;

    public interface OnTabSelectedListener {
        void onTabSelected(int index, boolean showPopup);
    }

    public void setOnTabSelectedListener(OnTabSelectedListener listener) {
        this.mTabListener = listener;
    }

我在这其中,加入了tab的切换动画。以及一些简单的事件监听,我想他能满足,我的需求了,至少不够,我还能提供其他的方法。

使用他很简单,只在布局当中加入替换我们的底部菜单,然后配置自定义的TabLinearLayoutTwo就行了。

主布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/frameLayout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

    </FrameLayout>

    <com.yange.carcaiwang.base.baseview.TabLinearLayoutTwo
        android:id="@+id/main_tab"
        android:layout_width="match_parent"
        android:layout_height="55dp"
        android:background="#f5f5f5">

    </com.yange.carcaiwang.base.baseview.TabLinearLayoutTwo>


</LinearLayout>

Mainactivity

public class MainActivity extends AppBaseActivity implements TabLinearLayoutTwo.OnTabSelectedListener {
    private TabLinearLayoutTwo tabLinearLayout;//底部菜单

    @Override
    protected void initViews(Bundle savedInstanceState) {
        setContentView(R.layout.act_main_layout);
        tabLinearLayout = (TabLinearLayoutTwo) findViewById(R.id.main_tab);
        tabLinearLayout.setOnTabSelectedListener(this);

    }
     //底部tab选中监听
    @Override
    public void onTabSelected(int index, boolean showPopup) {

    }
}

至于fragment的布局的建立和隐藏添加,我们在onTabSelected中,进行处理就行了。

猜你喜欢

转载自blog.csdn.net/zr940326/article/details/53224513
今日推荐