android原本没有segment控件,如果要最简单的实现方法就用多个Button来更改背景颜色实现。
这里讲的是自定义一个控件。网上各路大牛也发过类似的。我这里也做一下记录。
美工切了个图,要实现一个这样的效果,代码大多都摘抄自网上,做了一点修改。具体原理就不多说了。
一、首先自定义资源文件xml代码如下:
<declare-styleable name="SegmentControl">
<attr name="cornerRadius" format="dimension|reference" />
<attr name="scv_BackgroundSelectedColor" format="reference|color" />//选中segment的背景颜色
<attr name="scv_BackgroundNormalColor" format="reference|color" />//未选中segment的背景颜色
<attr name="scv_TextSelectedColor" format="reference|color" />//选中segment的文字颜色
<attr name="scv_TextNormalColor" format="reference|color" />//未选中segment的文字颜色
<attr name="scv_FrameColor" format="reference|color" />//segment边框的颜色
<attr name="scv_FrameWidth" format="reference|dimension" />//segment边框的宽度
<attr name="scv_FrameCornerRadius" format="reference|dimension" />//segment四个圆角的半径大小
<attr name="scv_TextSize" format="reference|dimension" />//文字大小
<attr name="scv_TextArray" format="reference" />//string数组,每一个string都会填充到一个segment中
<attr name="scv_SelectedIndex" format="reference|integer" />//默认选中的segment
<attr name="scv_SegmentPaddingHorizontal" format="reference|dimension" />//每一个segment内部的水平padding
<attr name="scv_SegmentPaddingVertical" format="reference|dimension" />每一个Segment的竖直方向的padding
<attr name="scv_Gradient" format="reference|boolean" />//Segment改变时是否使用颜色渐变效果
</declare-styleable>
二、自定义segment控件,这里用自定义view。代码如下:
package com.tang.segment.segmentcontrol;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.v4.view.ViewPager;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.lang.reflect.Field;
/**
* Created by tang on 2018/2/25.
*/
public class SegmentControl extends View {
/**
* onSegmentChanged function will be triggered if segment changed
*/
public interface OnSegmentChangedListener{
void onSegmentChanged(int newSelectedIndex);
}
private static final float TOUCHED_BACKGROUND_DARK_COEFFICIENT = 0.95F;
private static final int COLOR_PRIMARY_NORMAL = 0XFFFFFFFF;
private static final int COLOR_PRIMARY_SELECTED = 0XFF2CA99F;
private static final int DEFAULT_COLOR_BACKGROUND_SELECTED = COLOR_PRIMARY_SELECTED;
private static final int DEFAULT_COLOR_BACKGROUND_NORMAL = COLOR_PRIMARY_NORMAL;
private static final int DEFAULT_COLOR_TEXT_SELECTED = COLOR_PRIMARY_NORMAL;
private static final int DEFAULT_COLOR_TEXT_NORMAL = COLOR_PRIMARY_SELECTED;
private static final int DEFAULT_COLOR_FRAME = COLOR_PRIMARY_SELECTED;
private static final int DEFAULT_TEXT_SIZE_SP = 16;
private static final int DEFAULT_FRAME_WIDTH_PX = 2;
private static final int DEFAULT_FRAME_CORNER_RADIUS_PX = 0;
private static final int DEFAULT_SELECTED_INDEX = 0;
private static final int DEFAULT_SEGMENT_PADDING_HORIZONTAL = 16;
private static final int DEFAULT_SEGMENT_PADDING_VERTICAL = 12;
private static final boolean DEFAULT_IS_GRADIENT = false;
private String[] mTexts = null;
private int mColorBackgroundSelected = DEFAULT_COLOR_BACKGROUND_SELECTED;
private int mColorBackgroundNormal = DEFAULT_COLOR_BACKGROUND_NORMAL;
private int mColorTextSelected = DEFAULT_COLOR_TEXT_SELECTED;
private int mColorTextNormal = DEFAULT_COLOR_TEXT_NORMAL;
private int mColorFrame = DEFAULT_COLOR_FRAME;
private int mFrameWidth = DEFAULT_FRAME_WIDTH_PX;
private int mFrameCornerRadius = DEFAULT_FRAME_CORNER_RADIUS_PX;
private int mTextSize = 0;
private int mSelectedIndex = DEFAULT_SELECTED_INDEX;
//used in wrap_content mode
private int mSegmentPaddingHorizontal = DEFAULT_SEGMENT_PADDING_HORIZONTAL;
private int mSegmentPaddingVertical = DEFAULT_SEGMENT_PADDING_VERTICAL;
private boolean mIsGradient = DEFAULT_IS_GRADIENT;
private OnSegmentChangedListener mOnSegmentChangedListener;
private float unitWidth = 0;
private Paint paintText; //painter of the text
private Paint paintBackground; //painter of the background
private Paint paintFrame; //painter of the frame
private RectF rectF;
private RectF rectFArc;
private Path pathFrame;
private float textCenterYOffset;
private int preTouchedIndex = -1;
private int curTouchedIndex = -1;
private ViewPager viewPager;
public SegmentControl(Context context) {
super(context);
init();
}
public SegmentControl(Context context, AttributeSet attrs) {
super(context, attrs);
initAttr(context, attrs);
init();
}
public SegmentControl(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttr(context, attrs);
init();
}
private void initAttr(Context context, AttributeSet attrs) {
if (attrs == null) {
return;
}
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SegmentControl);
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
if(attr == R.styleable.SegmentControl_scv_BackgroundSelectedColor){
mColorBackgroundSelected = a.getColor(attr, DEFAULT_COLOR_BACKGROUND_SELECTED);
}else if(attr == R.styleable.SegmentControl_scv_BackgroundNormalColor){
mColorBackgroundNormal = a.getColor(attr, DEFAULT_COLOR_BACKGROUND_NORMAL);
}else if(attr == R.styleable.SegmentControl_scv_TextSelectedColor){
mColorTextSelected = a.getColor(attr, DEFAULT_COLOR_TEXT_SELECTED);
}else if(attr == R.styleable.SegmentControl_scv_TextNormalC