自定义TabLayout的实现

前言

项目需要做一个选项卡的功能,很简单,就是点击切换的效果,公共有这个控件,但是不太符合业务需求,所以自己花了半小时写了一个,很简单,继承自linearLayout,支持预置选择哪个选项卡,支持显示红点,支持选择回调。
项目很简单,一直在纠结要不要写博客,最后为了坚持还是写了,毕竟万变不离其宗,复杂的效果也是简单的逻辑一个个堆砌起来的。写一下,希望也能帮助一些初学者

效果图

照例,我们先看效果图有一个整体的认识
这里写图片描述
可以看到效果还是不错的,不过不支持横向滑动,你可以自己在外层嵌套一个横向滚动的scrollview来实现,或者更高级的自己去实现可横向滑动的tab。

怎么实现

这个demo也可以说是自定义控件的入门。
我们自己定义一个类TabLayout继承自LinearLayout,很开心的是我们并不需要重写OnLayout或者onMeasure方法,只需要根据我们的逻辑自己去实现就行了,只要你能够很顺畅的将这个Demo写完,我相信OnLayout onMeasure也不在话下,因为我们都是遍历子view进行相应的逻辑运算的。

继承控件LinearLayout,并在默认构造方法中去初始化一些参数

public class TabLayout extends LinearLayout {
    private Context mContext;
    private LayoutInflater mInflater;
    private String[] mTitles;
    private OnTabSelectListener mListener;//点击回调
    private SparseArray<View> mTitleViews;//保存一下我们的textView;
    private SparseArray<View> mLineViews;//保存一下我们的下划线


    public TabLayout(Context context) {
        this(context, null);

    }

    public TabLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        mInflater = LayoutInflater.from(context);
        mTitleViews = new SparseArray<>();
        mLineViews = new SparseArray<>();
        this.setOrientation(HORIZONTAL);
        this.setGravity(Gravity.CENTER_HORIZONTAL);
    }

给外部提供接口好让用户和使用listview等控件一样去使用

public void setTabSelectListener(OnTabSelectListener listener) {
        mListener = listener;
    }

    public void setData(String[] titles) {
        mTitles = titles;
        layoutViews();

    }

核心逻辑layoutViews()

private void layoutViews() {

        if (mTitles != null && mTitles.length != 0) {
            for (int i = 0; i < mTitles.length; i++) {
                final View childView = mInflater.inflate(R.layout.tab_layout_item, this, false);
                final TextView titleView = (TextView) childView.findViewById(R.id.hotel_tab_tv_title);
                TextView tvLine = (TextView) childView.findViewById(R.id.tv_line);
                if (i == 0) {//默认第一个高亮
                    titleView.setTextColor(mContext.getResources().getColor(R.color.main_green));
                    tvLine.setVisibility(VISIBLE);
                }
                titleView.setText(mTitles[i]);
                this.addView(childView);
                final int position = i;
                childView.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (mListener != null) {
                            mListener.onTabSelect(position);
                            setTabTitleColor(position);//刷新view状态
                        }
                    }
                });

                mTitleViews.put(i, titleView);
                mLineViews.put(i, tvLine);
            }

        }


    }

在这段逻辑中我们需要根据外部传来的数据源进行view的赋值 ,遍历外部数据源,根据外部数据源的数量生成等量的子view并将其添加进当前父view中,为了避免重复的findViewById,我们将我们需要的view添加进sparesArray中,以后面再次使用。
接下来就是提供外部接口去控制一些view的显示功能
很简单


    //控制哪个tab高亮
    public void setTabSelect(int position) {
        setTabTitleColor(position);
        if (mListener != null) {
            mListener.onTabSelect(position);
        }
    }

//控制红点显示
    public void setRedPointVisible(int position) {
        View childView = this.getChildAt(position);
        View billView = childView.findViewById(R.id.hotel_tab_tv_first_bill);
        billView.setVisibility(VISIBLE);

    }
//控制红点的隐藏
    public void setRedPointGone(int position) {
        View childView = this.getChildAt(position);
        View billView = childView.findViewById(R.id.hotel_tab_tv_first_bill);
        billView.setVisibility(GONE);

    }

就是这样,代码还是很简单的,权当一次记录学习

主代码调用方式如下

package com.lyd.tablayout;

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

import view.TabLayout;

public class MainActivity extends AppCompatActivity {

    private TabLayout mTabLayout;
    String[] mTitles = new String[]{"流行音乐", "经典音乐", "轻音乐"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        mTabLayout = (TabLayout) findViewById(R.id.tab_layout);

        mTabLayout.setData(mTitles);
        mTabLayout.setRedPointVisible(0);

        mTabLayout.setTabSelectListener(new TabLayout.OnTabSelectListener() {
            @Override
            public void onTabSelect(int position) {

                Toast.makeText(MainActivity.this, position + "", Toast.LENGTH_SHORT).show();
            }
        });

    }
}

代码已经上传到github
https://github.com/nbwzlyd/TabLayoutDemo
欢迎下载star

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值