Android仿IOS的Segmented Control 选项卡。

来源:互联网 发布:邮件传输协议端口号 编辑:程序博客网 时间:2024/06/01 09:01

参考Android仿IOS的Segmented Control 选项卡。
自定义View。

public class SwitchButton extends RadioGroup implements OnCheckedChangeListener {    private final int[] CHECKED_STATE = { android.R.attr.state_checked }, UNCHECKED_STATE = { -android.R.attr.state_checked };    /** 默认选项卡数量 */    private final static int DEFAULT_SWITCH_COUNT = 2;    private final static int EX = 5;// 余量    private ColorStateList mTextColor;    private int mParentWidth, mParentHeight;    private int mRadioStyle;    private float cornerRadius, textSize;    private int checkedColor, unCheckedColor, strokeColor, strokeWidth;    private CharSequence[] mTexts;    private int switchCount;    // 是否测量完毕    private boolean isMeasure;    private SparseArray<RadioButton> mRadioArrays;    private SparseArray<Drawable> mButtonDrawables;    private SparseArray<StateListDrawable> mStateDrawables;    private SparseIntArray mSparseIds;    private int mCurrentPosition;    private OnChangeListener changeListener;    /**     * @param context     */    public SwitchButton(Context context) {        super(context, null);    }    public SwitchButton(Context context, AttributeSet attrs) {        super(context, attrs);        TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.orientation, android.R.attr.layout_height });        setOrientation(a.getInt(0, LinearLayout.HORIZONTAL));        mParentHeight = a.getDimensionPixelSize(1, 0);        a.recycle();        a = context.obtainStyledAttributes(attrs, R.styleable.switchButton);        setTextColor(a.getColorStateList(R.styleable.switchButton_android_textColor));        setTextArray(a.getTextArray(R.styleable.switchButton_sw_textArray));        setSwitchCount(a.getInteger(R.styleable.switchButton_sw_switchCount, DEFAULT_SWITCH_COUNT));        setSwitchStyle(a.getResourceId(R.styleable.switchButton_sw_ThemeStyle, 0));        setCornerRadius(a.getDimension(R.styleable.switchButton_sw_CornerRadius, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5f, getResources().getDisplayMetrics())));        setCheckedColor(a.getColor(R.styleable.switchButton_sw_checkedColor, Color.GREEN));        setUnCheckedColor(a.getColor(R.styleable.switchButton_sw_unCheckedColor, Color.WHITE));        setStrokeColor(a.getColor(R.styleable.switchButton_sw_strokeColor, Color.GREEN));        setStrokeWidth((int) a.getDimension(R.styleable.switchButton_sw_strokeWidth, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1f, getResources().getDisplayMetrics())));        setTextSize(a.getDimension(R.styleable.switchButton_android_textSize, 0f));        a.recycle();        setOnCheckedChangeListener(this);    }    /**     * 初始化UI     *      * @param context     */    @SuppressWarnings("deprecation")    @SuppressLint("NewApi")    private void initUI(Context context) {        if (mTexts != null && mTexts.length != switchCount) {            throw new IllegalArgumentException("The textArray's length must equal to the switchCount");        }        if (mParentWidth == 0)            return;        ColorDrawable colorDrawable = new ColorDrawable();        LayoutParams mParams = new LayoutParams(mParentWidth / (switchCount > 2 ? switchCount : (switchCount + 1)), mParentHeight, 1);        for (int i = 0; i < switchCount; i++) {            if (mRadioArrays == null)                mRadioArrays = new SparseArray<RadioButton>();            RadioButton mRadioButton = mRadioArrays.get(i, createRadioView());            mRadioButton.setLayoutParams(mParams);            mRadioButton.setButtonDrawable(mButtonDrawables != null ? mButtonDrawables.get(i, colorDrawable) : colorDrawable);            if (Build.VERSION.SDK_INT >= 16) {                mRadioButton.setBackground(getStateDrawable(i));            } else {                mRadioButton.setBackgroundDrawable(getStateDrawable(i));            }            mRadioButton.setText(mTexts[i]);            if (mRadioButton.getId() < 0) {                int id = getViewId();                if (mSparseIds == null)                    mSparseIds = new SparseIntArray();                mSparseIds.put(i, id);                mRadioButton.setId(id);            } else {                removeView(mRadioButton);            }            mRadioButton.setChecked(mCurrentPosition == i);            addView(mRadioButton, i);            mRadioArrays.put(i, mRadioButton);        }    }    private Drawable getStateDrawable(int i) {        if (mStateDrawables == null)            mStateDrawables = new SparseArray<StateListDrawable>();        StateListDrawable mStateListDrawable = mStateDrawables.size() >= i + 1 && (i != switchCount - 1 || i == switchCount - 1) ? null : mStateDrawables.get(i);        if (mStateListDrawable == null) {            float leftRadius = i == 0 ? cornerRadius : 0;            float rightRadius = i == 0 ? 0 : i == switchCount - 1 ? cornerRadius : 0;            float[] cRadius = { leftRadius, leftRadius, rightRadius, rightRadius, rightRadius, rightRadius, leftRadius, leftRadius };            mStateListDrawable = new StateListDrawable();            GradientDrawable cornerDrawable = new GradientDrawable();            cornerDrawable.setColor(checkedColor);            cornerDrawable.setCornerRadii(cRadius);            mStateListDrawable.addState(CHECKED_STATE, cornerDrawable);            cornerDrawable = new GradientDrawable();            cornerDrawable.setColor(unCheckedColor);            cornerDrawable.setStroke(strokeWidth, strokeColor);            cornerDrawable.setCornerRadii(cRadius);            mStateListDrawable.addState(UNCHECKED_STATE, cornerDrawable);            mStateDrawables.put(i, mStateListDrawable);        }        return mStateListDrawable;    }    private RadioButton createRadioView() {        RadioButton mRadioButton = new RadioButton(getContext(), null, mRadioStyle > 0 ? mRadioStyle : android.R.attr.radioButtonStyle);        if (mRadioStyle == 0) {            mRadioButton.setGravity(Gravity.CENTER);            mRadioButton.setEllipsize(TruncateAt.END);        }        if (mTextColor != null)            mRadioButton.setTextColor(mTextColor);        if (textSize > 0)            mRadioButton.setTextSize(textSize);        return mRadioButton;    }    @Deprecated    public void initialize() {        notifyDataSetChange();    }    /**     * 刷新数据(Button数量跟随刷新的文本数据变化)     */    public void notifyDataSetChange() {        removeAllViews();        switchCount = mTexts != null ? mTexts.length : switchCount;        initUI(getContext());    }    @Override    public void onWindowFocusChanged(boolean hasFocus) {        super.onWindowFocusChanged(hasFocus);        if (!isMeasure) {            initUI(getContext());            isMeasure = !isMeasure;        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mParentWidth = widthMeasureSpec - EX;        mParentHeight = mParentHeight == 0 ? heightMeasureSpec : mParentHeight;    }    @Override    public void onCheckedChanged(RadioGroup group, int checkedId) {        if (changeListener != null)            changeListener.onChange(mSparseIds.indexOfValue(checkedId));    }    /**     * 设置当前选中项     *      * @param selectedPosition     */    public void setCurrentPosition(int selectedPosition) {        if (selectedPosition >= 0 && selectedPosition <= switchCount) {            mCurrentPosition = selectedPosition;        }    }    /**     * 设置选中项     *      * @param selectedPosition     */    public void setCheckedPosition(int selectedPosition) {        if (selectedPosition >= 0 && selectedPosition <= switchCount) {            mCurrentPosition = selectedPosition;            if (mSparseIds != null)                check(mSparseIds.get(mSparseIds.keyAt(selectedPosition)));        }    }    public void setTextColor(ColorStateList mTextColor) {        this.mTextColor = mTextColor;    }    public void setSwitchStyle(int mSwitchStyle) {        this.mRadioStyle = mSwitchStyle;    }    public void setTextArray(CharSequence[] mTexts) {        this.mTexts = mTexts;    }    public int getSwitchCount() {        return switchCount;    }    public void setParentWidth(int mParentWidth) {        this.mParentWidth = mParentWidth;    }    public void setParentHeight(int mParentHeight) {        this.mParentHeight = mParentHeight;    }    public void setSwitchCount(int switchCount) {        this.switchCount = switchCount < 2 ? DEFAULT_SWITCH_COUNT : switchCount;        if (mButtonDrawables == null)            mButtonDrawables = new SparseArray<Drawable>();    }    public void setCornerRadius(float cornerRadius) {        this.cornerRadius = cornerRadius;    }    public void setCheckedColor(int checkedColor) {        this.checkedColor = checkedColor;    }    public void setUnCheckedColor(int unCheckedColor) {        this.unCheckedColor = unCheckedColor;    }    public void setStrokeColor(int strokeColor) {        this.strokeColor = strokeColor;    }    public void setStrokeWidth(int strokeWidth) {        this.strokeWidth = strokeWidth;    }    public void setTextSize(float textSize) {        this.textSize = textSize;    }    public void setSwitchButton(int position, int mDrawableResId) {        mButtonDrawables.put(position, getResources().getDrawable(mDrawableResId));    }    public void setOnChangeListener(OnChangeListener eventListener) {        this.changeListener = eventListener;    }    public interface OnChangeListener {        public void onChange(int position);    }    private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);    public int getViewId() {        for (;;) {            final int result = sNextGeneratedId.get();            // aapt-generated IDs have the high byte nonzero; clamp to the range            // under that.            int newValue = result + 1;            if (newValue > 0x00FFFFFF)                newValue = 1; // Roll over to 1, not 0.            if (sNextGeneratedId.compareAndSet(result, newValue)) {                return result;            }        }    }}

values下创建array.xml

<?xml version="1.0" encoding="utf-8"?><resources>    <string-array name="test">        <item></item>        <item></item>    </string-array></resources>

arrts.xml

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="switchButton">        <attr name="android:textColor" />        <attr name="android:textSize" />        <attr name="sw_textArray" format="string" />        <attr name="sw_switchCount" format="integer" />        <attr name="sw_ThemeStyle" format="reference" />        <attr name="sw_CornerRadius" format="dimension" />        <attr name="sw_checkedColor" format="color|reference" />        <attr name="sw_unCheckedColor" format="color|reference" />        <attr name="sw_strokeColor" format="color|reference" />        <attr name="sw_strokeWidth" format="dimension" />    </declare-styleable></resources>

dimens.xml

<resources>    <dimen name="icon_arrow_width">16dp</dimen>    <dimen name="body_margin">10dp</dimen>    <dimen name="twenty">20dp</dimen></resources>

drawable.xml 的 switch_textcolor_selector.xml

<?xml version="1.0" encoding="utf-8"?><!-- title sitch --><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_checked="false" android:color="@color/colorPrimary"/>    <item android:state_checked="true" android:color="@color/white"/></selector>
  mSwitchButton = (SwitchButton) findViewById(R.id.switchButton);        mSwitchButton.setOnChangeListener(new SwitchButton.OnChangeListener() {            @Override            public void onChange(int position) {                if (position==0){                    FragmentManager fm = getFragmentManager();                    final FragmentTransaction ft = fm.beginTransaction();                    fragment1 = new Fragment1();                    ft.replace(android.R.id.content, fragment1);                    ft.commit();                }                else {                    FragmentManager fm = getFragmentManager();                    final FragmentTransaction ft = fm.beginTransaction();                    fragment2 = new Fragment2();                    ft.replace(android.R.id.content, fragment2);                    ft.commit();                }            }        });

效果
这里写图片描述

原创粉丝点击