Android开发自定义控件实现一个球赛胜负数统计条

效果如下图所示,展示两个球队交战胜负信息

首先此控件在水平方向均分为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();
    }
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值