效果如下图所示,展示两个球队交战胜负信息
首先此控件在水平方向均分为5份,第一份和第五份留白不绘制内容
第二三四份分别绘制3列数据
垂直方向分为N份,N和输入数据的最大值有关
垂直方向下边百分之二十的空间显示文本,上边百分之八十的空间显示指定数量的横线,横线上方显示横线的数量
因为垂直方向做了N等分,因此垂直方向相当于有了一个刻度,经过计算每条横线绘制在属于自己的刻度处即可
完整代码如下:
public class GameOutcomeBar extends View {
private Context context;
/*y方向的刻度,数据越多,刻度值越小*/
private int MAX_GRADE=20;
/*记录 胜场 平局 负场 画笔颜色*/
private int mWinColor;
private int mDrawColor;
private int mLoseColor;
/*胜场 平局 负场 数量*/
private int mWins;
private int mDraws;
private int mLoses;
private TypedValue typedValue;
/*绘制图形的画笔*/
private Paint paintBar = new Paint();
/*绘制文字的画笔*/
private Paint paintText = new Paint();
public GameOutcomeBar(Context context) {
super(context);
this.context=context;
init();
}
public GameOutcomeBar(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
init();
}
public GameOutcomeBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context=context;
init();
}
private void init() {
/*数据初始化*/
mWinColor = Color.BLUE;
mDrawColor =Color.YELLOW;
mLoseColor =Color.GREEN;
mWins =0;
mDraws =0;
mLoses =0;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*总宽度*/
float totalWidth =getWidth();
/*除了下边文字以外的高度,下边文字占据的高度是总高度的百分之二十*/
float totalBarHeight =getHeight()*0.8f;
/*画笔大小的标准*/
float paintSize = DensityUtil.dip2px(getContext(),100);
/*控件整个宽度分为5列,第一列和第五列留白,第二三四列分别绘制胜场、平局和负场*/
float columnLength = totalWidth /5;
/*三列之间的间距*/
float columnSpan = totalWidth /40;
/*绘制横线的画笔设置*/
paintBar.reset();
paintBar.setStrokeWidth(paintSize * 1f/2 / MAX_GRADE / 3);
paintBar.setStyle(Paint.Style.STROKE);
paintBar.setAntiAlias(true);
/*绘制胜场*/
paintBar.setColor(mWinColor);
/*循环绘制横线*/
for (int i = 0; i< mWins; i++) {
/*计算每一条横线的垂直坐标位置*/
float eachLineHeight=totalBarHeight * (1f-(i+2f) / MAX_GRADE);
/*合适的位置开始绘制横线*/
canvas.drawLine(totalWidth * 1 / 5 - columnSpan,eachLineHeight ,
totalWidth * 2 / 5 - columnSpan, eachLineHeight,paintBar);
}
/*绘制文字画笔设置*/
paintText.reset();
paintText.setStyle(Paint.Style.STROKE);
paintText.setAntiAlias(true);
/*文字从中间开始绘制*/
paintText.setTextAlign(Paint.Align.CENTER);
typedValue=new TypedValue();
/*设置文字画笔颜色*/
context.getTheme().resolveAttribute(R.attr.maintextclor, typedValue,true);
paintText.setColor(getResources().getColor(typedValue.resourceId));
/*设置文字画笔大小*/
paintText.setTextSize(paintSize / 5);
/*绘制文字,在横线列的最上方绘制数字*/
canvas.drawText("" + mWins, totalWidth * 1 / 5 - columnSpan + columnLength /2, totalBarHeight * (1f- (mWins +2f) / MAX_GRADE), paintText);
/*更改文字画笔大小,在横线列的下方绘制文本*/
paintText.setTextSize(paintSize / 15);
Paint.FontMetrics fontMetrics = paintText.getFontMetrics();
canvas.drawText("胜场" , totalWidth * 1 / 5 - columnSpan + columnLength /2, totalBarHeight-fontMetrics.top, paintText);
/*绘制平局*/
paintBar.setColor(mDrawColor);
for (int i = 0; i< mDraws; i++) {
float eachLineHeight=totalBarHeight * (1f-(i+2f) / MAX_GRADE);
canvas.drawLine(totalWidth * 2 / 5 , eachLineHeight,
totalWidth * 3 / 5 , eachLineHeight,paintBar);
}
paintText.setTextSize(paintSize / 5);
canvas.drawText("" + mDraws, totalWidth * 2 / 5 + columnLength / 2, totalBarHeight * (1f - (mDraws +2f) / MAX_GRADE), paintText);
paintText.setTextSize(paintSize / 15);
fontMetrics = paintText.getFontMetrics();
canvas.drawText("平局" , totalWidth * 2 / 5+ columnLength /2, totalBarHeight -fontMetrics.top, paintText);
/*绘制负场*/
paintBar.setColor(mLoseColor);
for (int i = 0; i< mLoses; i++) {
float eachLineHeight=totalBarHeight * (1f-(i+2f) / MAX_GRADE);
canvas.drawLine(totalWidth * 3 / 5 + columnSpan, eachLineHeight,
totalWidth * 4 / 5 + columnSpan, eachLineHeight,paintBar);
}
paintText.setTextSize(paintSize / 5);
canvas.drawText("" + mLoses, totalWidth * 3 / 5 + columnSpan + columnLength /2, totalBarHeight * (1f - (mLoses +2f) / MAX_GRADE), paintText);
paintText.setTextSize(paintSize / 15);
fontMetrics = paintText.getFontMetrics();
canvas.drawText("负场" , totalWidth * 3 / 5 + columnSpan + columnLength /2, totalBarHeight-fontMetrics.top, paintText);
}
public void setWinsDrawLose(int wins,int draw, int lose) {
if (wins<0||draw<0||lose<0) {
throw new IllegalArgumentException("参数不能小于零");
}
this.mWins =wins;
this.mDraws =draw;
this.mLoses =lose;
this.MAX_GRADE=Math.max(wins,Math.max(draw,lose))+15;
this.invalidate();
}
}