最近项目中有用到一个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的全部逻辑。