
最近項目中有用到一個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 / , ViewGroup.LayoutParams.MATCH_PARENT);
LinearLayout.LayoutParams layoutParams2 = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
for (int i = ; 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), , , );
linearLayout.addView(textView);
linearLayout.addView(imageView);
this.addView(linearLayout);
}
}
@Override
public void onClick(View v) {
for (int i = ; 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用的是一個線性布局。
然後就是每個Tab中的TextView(文字)和ImageView(右側小箭頭圖檔)的參數(設定的都是包裹内容)。
在然後就是周遊傳遞過來得資料集合。(有多少個資料就要建立多少個Tab)
for (int i = ; 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), , , );
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), , , );
linearLayout.addView(textView);
linearLayout.addView(imageView);
把每個Tab添加到父容器中:
this.addView(linearLayout);
最後看點選事件:
@Override
public void onClick(View v) {
for (int i = ; 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的全部邏輯。