自定義View之仿ios分段選擇器
阿新 • • 發佈:2018-12-14
一:效果
1.1 可動態新增或刪除tab,更改指定tab的文字。
二:實現思路
- 自定義view,實現效果
- 動態建立textview,有幾個tab建立幾個textview
- 第一個tab和最後一個tab為圓角矩形,其餘的為直角矩形,通過shape檔案完成
- 預設選中第一個tab選項,更改背景顏色和textview顏色,更改其餘所有tab的顏色
- 設定點選事件,動態更改每一個tab的顏色
三:程式碼實現
思路我們已經清晰了,下面按照我們的思路編碼就行了,沒什麼難度,下面我就直接貼出程式碼了,有需要的同學直接拿去用就好了。
在這裡重點說一下每個tab中間的分割線,如果不單獨做處理的話,你會發現tab的分割線和邊框線寬度不一致,影響整體美觀度,是因為第一個tab繪製了一遍分割線,第二個tab又繪製了一遍分割線。
博主的處理方式為:
- 為整個自定義view設定一個整體的邊框
- 每個tab只設置右邊的一條邊框,最後一個tab不設定邊框,採用 <layer-list> 實現
3.1 自定義view程式碼
package com.zuohp.jstt.widget; import android.content.Context; import android.content.res.ColorStateList; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; import com.zuohp.jstt.R; import java.util.ArrayList; import java.util.List; public class SegmentView extends LinearLayout { // 實現不同的按鈕狀態,不同的顏色 ColorStateList cs1 = getResources().getColorStateList(R.color.white); ColorStateList cs2 = getResources().getColorStateList(R.color.colorPrimaryDark); private onSegmentViewClickListener segmentListener; //存放textview的集合 List<TextView> views = new ArrayList<TextView>(); // 這是程式碼載入ui必須重寫的方法 public SegmentView(Context context) { super(context); } // 這是在xml佈局使用必須重寫的方法 public SegmentView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public SegmentView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } //主要方法 public void contentView(String[] text,int dp){ this.removeAllViews(); this.setBackgroundResource(R.drawable.segment_lin_bg); for (int i = 0; i < text.length; i++) { final TextView textView = new TextView(getContext()); textView.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1)); textView.setText(text[i]); textView.setGravity(Gravity.CENTER); textView.setPadding(5, 14, 5, 14); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, dp); if (i==0){//第一個 textView.setBackgroundResource(R.drawable.segment_left); textView.setSelected(true); textView.setTextColor(cs2); }else if (i==text.length-1){//最後一個 textView.setBackgroundResource(R.drawable.segment_right); textView.setTextColor(cs1); }else {//中間的 textView.setBackgroundResource(R.drawable.segment_centre); textView.setTextColor(cs1); } //設定id方便在設定點選事件的時候區分是那個view textView.setId(i); views.add(textView); this.addView(textView); //設定點選事件 textView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { for (TextView view:views) { view.setSelected(false); view.setTextColor(cs1); } views.get(v.getId()).setSelected(true); views.get(v.getId()).setTextColor(cs2); if (segmentListener != null) { segmentListener.onSegmentViewClick(textView, v.getId()); } } }); } this.invalidate();//重新draw() } /** * 設定控制元件顯示的文字 * * @param text * @param position */ public void setSegmentText(CharSequence text, int position) { } // 定義一個介面接收點選事件 public interface onSegmentViewClickListener { public void onSegmentViewClick(View view, int postion); } public void setOnSegmentViewClickListener(onSegmentViewClickListener segmentListener) { this.segmentListener = segmentListener; } }
3.2 shape檔案 ---- segment_lin_bg
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:topLeftRadius="20dp" android:topRightRadius="20dp" android:bottomRightRadius="20dp" android:bottomLeftRadius="20dp"/> <padding android:right="1dp" android:left="1dp" android:top="1dp" android:bottom="1dp" /> <stroke android:width="1dp" android:color="@color/white" /> </shape>
3.3 shape檔案 ---- segment_left
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<shape>
<solid android:color="@color/white"/>
<corners
android:bottomLeftRadius="20dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="20dp"
android:topRightRadius="0dp" />
</shape>
</item>
<item>
<layer-list>
<item>
<shape>
<solid android:color="@color/colorPrimaryDark" />
<corners
android:bottomLeftRadius="20dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="20dp"
android:topRightRadius="0dp" />
</shape>
</item>
<item
android:width="1dp"
android:gravity="right" >
<shape>
<solid
android:color="@color/white"/>
</shape>
</item>
</layer-list>
</item>
</selector>
3.4 shape檔案 ---- segment_right
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<shape>
<solid android:color="@color/white" />
<corners
android:bottomLeftRadius="0dp"
android:bottomRightRadius="20dp"
android:topLeftRadius="0dp"
android:topRightRadius="20dp" />
</shape>
</item>
<item>
<shape>
<solid android:color="@color/colorPrimaryDark" />
<corners
android:bottomLeftRadius="0dp"
android:bottomRightRadius="20dp"
android:topLeftRadius="0dp"
android:topRightRadius="20dp" />
</shape>
</item>
</selector>
3.5 shape檔案 ---- segment_centre
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<shape>
<solid android:color="@color/white"/>
</shape>
</item>
<item>
<layer-list>
<item>
<shape>
<solid android:color="@color/colorPrimaryDark" />
</shape>
</item>
<item
android:width="1dp"
android:gravity="right" >
<shape>
<solid
android:color="@color/white"/>
</shape>
</item>
</layer-list>
</item>
</selector>
3.6 xml檔案
<android.support.v7.widget.Toolbar
android:id="@+id/mToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
app:contentInsetStart="0dp"
android:background="@color/colorPrimaryDark">
<com.zuohp.jstt.widget.SegmentView
android:id="@+id/segmentview"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal"
>
</com.zuohp.jstt.widget.SegmentView>
</android.support.v7.widget.Toolbar>
3.7 測試程式碼
SegmentView segmentView = findViewById(R.id.segmentview);
segmentView.contentView(new String[]{"TAB1","TAB2","TAB3"},16);
segmentView.setOnSegmentViewClickListener(new SegmentView.onSegmentViewClickListener() {
@Override
public void onSegmentViewClick(View view, int postion) {
switch (postion){
case 0:
Toast.makeText(MainActivity.this,"點選了tab1",Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(MainActivity.this,"點選了tab2",Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(MainActivity.this,"點選了tab3",Toast.LENGTH_SHORT).show();
break;
}
}
});
四:結語
如有更好的方式或者不對的地方,歡迎指出!
祝:工作順利!