先上一个效果图
其实只有一个很简单的展示效果,不存在滑动效果,所以控件宽度可以设定为match-parent 或者固定dp值。(没有计算控件的总体宽高)
好了,下边开始说我写这个小控件的步骤。
1、根据效果图,首先画出中间的渐变色矩形
把矩形,矩形上边的数据和矩形下边的刻度分为3份,每份所占高度相同
float recHeight = getHeight / 3;
设置渐变色区域 colors 为渐变色 颜色数组
LinearGradient shader = new LinearGradient(0, 0, 1000, 0, colors, null, Shader.TileMode.CLAMP);
mPaint.setShader(shader);
canvas.drawRect(0, rectHeight, getWidth(), 2 * rectHeight, mPaint);
2、画刻度线和刻度值
mPaint.setColor(Color.BLACK);
String index = showItems[i] + "";
float txtWidth = px2dip(mContext, calculateTextWidth(index)) / 2f;
canvas.drawText(index, startX * width - txtWidth, rectHeight * 2.6f, mPaint);
3.画程度
float stringWidth = px2dip(mContext, calculateTextWidth(itemTitle[i])) / 2f;
if (i < showItems.length - 1) {
float x = (float) showItems[i + 1] / viewAlls;
float xstart = (x + startX) * width;
canvas.drawText(itemTitle[i], xstart / 2 - stringWidth, 0.5f * rectHeight, mPaint);
} else {
float start = (startX + 1f) * width;
canvas.drawText(itemTitle[i], start / 2 - stringWidth, 0.5f * rectHeight, mPaint);
}
4.倒三角
float triangleStart = (showIndex / viewAlls) * width;
//三角形起点
mPath.moveTo(triangleStart - 20,0.7f * rectHeight);
mPath.lineTo(triangleStart + 20,0.7f * rectHeight);
mPath.lineTo(triangleStart ,rectHeight);
mPath.close(); // 使这些点构成封闭的多边形
canvas.drawPath(mPath, mPaint);
然后就完成了这样一个程度标尺。
public class DegreeRulerView extends View {
private Paint mPaint;
private Path mPath;
//渐变色颜色数组
private int[] colors = {Color.parseColor("#8FF0D2"), Color.parseColor("#F5DF23"), Color.parseColor("#FA3F04")};
//总刻度数量
private int viewAlls = 35;
//需要显示的刻度
private int[] showItems;
//显示刻度对应的标题
private String[] itemTitle;
//倒三角显示位置
private float showIndex;
private Context mContext;
private float fontSize = 30f;
private DisplayMetrics metrics = null;
public DegreeRulerView(Context context) {
this(context, null);
}
public DegreeRulerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DegreeRulerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
metrics = new DisplayMetrics();
WindowManager wmg = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
wmg.getDefaultDisplay().getMetrics(metrics);
mPaint = new Paint();
mPath = new Path();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
mPaint.setTextSize(fontSize);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//根据设计图分成3个部分,每个部分高度相同
float rectHeight = getHeight() / 3;
//画矩形框
//设置渐变色区域
LinearGradient shader = new LinearGradient(0, 0, 1000, 0, colors, null, Shader.TileMode.CLAMP);
mPaint.setShader(shader);
canvas.drawRect(0, rectHeight, getWidth(), 2 * rectHeight, mPaint);
//清空渐变色区域,不然刻度线,刻度值都会是渐变色的
int width = getWidth();
mPaint.setShader(null);
for (int i = 0; i < showItems.length; i++) {
float startX = (float) showItems[i] / viewAlls;
//画刻度线
mPaint.setColor(Color.WHITE);
canvas.drawLine(startX * width, rectHeight * 1.4f, startX * width, rectHeight * 2f, mPaint);
//画刻度值
mPaint.setColor(Color.BLACK);
String index = showItems[i] + "";
float txtWidth = px2dip(mContext, calculateTextWidth(index)) / 2f;
canvas.drawText(index, startX * width - txtWidth, rectHeight * 2.6f, mPaint);
//画程度
float stringWidth = px2dip(mContext, calculateTextWidth(itemTitle[i])) / 2f;
if (i < showItems.length - 1) {
float x = (float) showItems[i + 1] / viewAlls;
float xstart = (x + startX) * width;
canvas.drawText(itemTitle[i], xstart / 2 - stringWidth, 0.5f * rectHeight, mPaint);
} else {
float start = (startX + 1f) * width;
canvas.drawText(itemTitle[i], start / 2 - stringWidth, 0.5f * rectHeight, mPaint);
}
}
//倒三角形
float triangleStart = (showIndex / viewAlls) * width;
//三角形起点
mPath.moveTo(triangleStart - 20,0.7f * rectHeight);
mPath.lineTo(triangleStart + 20,0.7f * rectHeight);
mPath.lineTo(triangleStart ,rectHeight);
mPath.close(); // 使这些点构成封闭的多边形
canvas.drawPath(mPath, mPaint);
}
public void setColors(int[] colors) {
this.colors = colors;
}
public void setViewAlls(int viewAlls) {
this.viewAlls = viewAlls;
}
public void setShowItems(int[] showItems) {
this.showItems = showItems;
}
public void setItemTitle(String[] itemTitle) {
this.itemTitle = itemTitle;
}
public void setShowIndex(float showIndex) {
this.showIndex = showIndex;
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
/**
* 获取TextView中文本的宽度
*/
private float calculateTextWidth(String text) {
if (TextUtils.isEmpty(text)) {
return 0;
}
TextPaint textPaint = new TextPaint();
textPaint.setTextSize(fontSize * metrics.scaledDensity);
final float textWidth = textPaint.measureText(text);
return textWidth;
}
}
使用方法:
<com.xw.example.DegreeRulerView
android:id="@+id/rulerView"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="20dp"
/>
rulerView.setViewAlls(35);
rulerView.setItemTitle(title);
rulerView.setShowItems(index);
rulerView.setShowIndex(10f);