自定义TabLayout

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq77485042/article/details/80164054

这里写图片描述

最近项目中有用到一个TabLayout,如上图效果。

先说说需求。

1.Tab的个数是动态变化的。
2.4个Tab占满一个屏幕,多余部分往右滑动过来。
3.点击后右侧小图标变化样式。

思路:
1.布局的话使用LinearLayout布局,放在HorizontalScrollView中。这样就实现了滚动效果。

2.获取到屏幕的宽度除以4设置成里面每个Tab的的宽度。

3.每个Tab使用的也是一个LinearLayout,左侧是一个TextView,右侧是一个ImageView。

先上代码:

public class MyTabLayout extends LinearLayout implements View.OnClickListener {
    private final int width;
    private Context context;
    private List<LinearLayout> linearLayoutList = new ArrayList<>();
    private List<ImageView> imageViewList = new ArrayList<>();
    private OnItemClickListener onItemClickListener;

    public OnItemClickListener getOnItemClickListener() {
        return onItemClickListener;
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    public MyTabLayout(Context context) {
        this(context, null);
    }

    public MyTabLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        width = wm.getDefaultDisplay().getWidth();
    }

    public void setData(List<String> strings) {
        LinearLayout.LayoutParams layoutParams = new LayoutParams(width / 4, ViewGroup.LayoutParams.MATCH_PARENT);
        LinearLayout.LayoutParams layoutParams2 = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        for (int i = 0; i < strings.size(); i++) {
            LinearLayout linearLayout = new LinearLayout(context);
            linearLayout.setLayoutParams(layoutParams);
            linearLayout.setGravity(Gravity.CENTER);
            linearLayout.setId(i);
            linearLayout.setOnClickListener(this);
            linearLayoutList.add(linearLayout);

            TextView textView = new TextView(context);
            textView.setText(strings.get(i));
            textView.setLayoutParams(layoutParams2);

            ImageView imageView = new ImageView(context);
            imageView.setLayoutParams(layoutParams2);
            imageView.setImageResource(R.mipmap.xiangxia2);
            imageViewList.add(imageView);
            imageView.setPadding(context.getResources().getDimensionPixelOffset(R.dimen.x10), 0, 0, 0);
            linearLayout.addView(textView);
            linearLayout.addView(imageView);

            this.addView(linearLayout);
        }
    }

    @Override
    public void onClick(View v) {
        for (int i = 0; i < linearLayoutList.size(); i++) {
            if (v.getId() == linearLayoutList.get(i).getId()) {
                imageViewList.get(i).setImageResource(R.mipmap.xiangxia1);
                if (getOnItemClickListener() != null) {
                    onItemClickListener.onItemClick(i);
                }
            } else {
                imageViewList.get(i).setImageResource(R.mipmap.xiangxia2);
            }
        }
    }

    public interface OnItemClickListener {
        void onItemClick(int position);
    }
}

用法如下:

1.在xml布局文件中放入控件:

<HorizontalScrollView
        android:id="@+id/hsv"
        android:layout_width="match_parent"
        android:layout_height="@dimen/x68"
        android:layout_marginTop="@dimen/x2"
        android:background="#ffffff"
        android:scrollbars="none"
        app:layout_constraintTop_toBottomOf="@+id/rg">

        <com.msyds.app.common.widget.MyTabLayout
            android:id="@+id/tab_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal" />
    </HorizontalScrollView>

2.在Activity或者Fragment中:

@Bind(R.id.tab_layout)
MyTabLayout tabLayout;

初始化控件:我这里用到的是ButterKnife框架没用过的人可以参考:https://blog.csdn.net/qq77485042/article/details/77751400

3.添加数据和监听器:

List<String> strings = new ArrayList<>();
        strings.add("区域");
        strings.add("仓库");
        strings.add("品牌");
        strings.add("开票");
        strings.add("结算");
        strings.add("类型");
        tabLayout.setData(strings);
        tabLayout.setOnItemClickListener(this);

4.监听器回调:

@Override
    public void onItemClick(int position) {
        ToastUtil.show(position + "");
    }

以上就完成了控件的使用。

下面分析一下每个步骤:

在初始化的时候拿到屏幕的最大宽度,因为除以4就是每个Tab的宽度:

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
width = wm.getDefaultDisplay().getWidth();

然后就是最核心的,setData()方法了。

在setData()中先创建每个Tab的参数,在这里我每个Tab用的是一个线性布局。

LinearLayout.LayoutParams layoutParams = new LayoutParams(width / 4, ViewGroup.LayoutParams.MATCH_PARENT);

然后就是每个Tab中的TextView(文字)和ImageView(右侧小箭头图片)的参数(设置的都是包裹内容)。

LinearLayout.LayoutParams layoutParams2 = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

在然后就是遍历传递过来得数据集合。(有多少个数据就要创建多少个Tab)

for (int i = 0; i < strings.size(); i++) {
            LinearLayout linearLayout = new LinearLayout(context);
            linearLayout.setLayoutParams(layoutParams);
            linearLayout.setGravity(Gravity.CENTER);
            linearLayout.setId(i);
            linearLayout.setOnClickListener(this);
            linearLayoutList.add(linearLayout);

            TextView textView = new TextView(context);
            textView.setText(strings.get(i));
            textView.setLayoutParams(layoutParams2);

            ImageView imageView = new ImageView(context);
            imageView.setLayoutParams(layoutParams2);
            imageView.setImageResource(R.mipmap.xiangxia2);
            imageViewList.add(imageView);
            imageView.setPadding(context.getResources().getDimensionPixelOffset(R.dimen.x10), 0, 0, 0);
            linearLayout.addView(textView);
            linearLayout.addView(imageView);

            this.addView(linearLayout);
        }

创建每个Tab的线性布局,设置id,设置点击事件,把linearLayout加入到linearLayout的集合中。

LinearLayout linearLayout = new LinearLayout(context);
            linearLayout.setLayoutParams(layoutParams);
            linearLayout.setGravity(Gravity.CENTER);
            linearLayout.setId(i);
            linearLayout.setOnClickListener(this);
            linearLayoutList.add(linearLayout);

创建Tab的文字和右侧图片并添加到Tab中。

TextView textView = new TextView(context);
            textView.setText(strings.get(i));
            textView.setLayoutParams(layoutParams2);

            ImageView imageView = new ImageView(context);
            imageView.setLayoutParams(layoutParams2);
            imageView.setImageResource(R.mipmap.xiangxia2);
            imageViewList.add(imageView);
            imageView.setPadding(context.getResources().getDimensionPixelOffset(R.dimen.x10), 0, 0, 0);
            linearLayout.addView(textView);
            linearLayout.addView(imageView);

把每个Tab添加到父容器中:

this.addView(linearLayout);

最后看点击事件:

@Override
    public void onClick(View v) {
        for (int i = 0; i < linearLayoutList.size(); i++) {
            if (v.getId() == linearLayoutList.get(i).getId()) {
                imageViewList.get(i).setImageResource(R.mipmap.xiangxia1);
                if (getOnItemClickListener() != null) {
                    onItemClickListener.onItemClick(i);
                }
            } else {
                imageViewList.get(i).setImageResource(R.mipmap.xiangxia2);
            }
        }
    }

遍历线性布局集合也就是Tab的集合,判断点击的Tab是哪一个给与对应的图片切换和回调。

以上就是TabLayout的全部逻辑。

猜你喜欢

转载自blog.csdn.net/qq77485042/article/details/80164054