1. 程式人生 > >自定義View之仿ios分段選擇器

自定義View之仿ios分段選擇器

一:效果

1.1 可動態新增或刪除tab,更改指定tab的文字。

二:實現思路

  1. 自定義view,實現效果
  2. 動態建立textview,有幾個tab建立幾個textview
  3. 第一個tab和最後一個tab為圓角矩形,其餘的為直角矩形,通過shape檔案完成
  4. 預設選中第一個tab選項,更改背景顏色和textview顏色,更改其餘所有tab的顏色
  5. 設定點選事件,動態更改每一個tab的顏色

三:程式碼實現

思路我們已經清晰了,下面按照我們的思路編碼就行了,沒什麼難度,下面我就直接貼出程式碼了,有需要的同學直接拿去用就好了。

在這裡重點說一下每個tab中間的分割線,如果不單獨做處理的話,你會發現tab的分割線和邊框線寬度不一致,影響整體美觀度,是因為第一個tab繪製了一遍分割線,第二個tab又繪製了一遍分割線。

博主的處理方式為:

  1. 為整個自定義view設定一個整體的邊框
  2. 每個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;
                }
            }
        });

四:結語

如有更好的方式或者不對的地方,歡迎指出!

祝:工作順利!