Android进阶之路 - 静态等级进度条

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_20451879/article/details/87930949
此篇应该算一个基础的自定义控件入门,内部没有去写自定义属性 ~

目录

  • 实现效果
  • 了解部分
  • 核心部分
  • 使用部分

实现效果

在这里插入图片描述

了解部分

  1. 创建画笔
	Paint  paint = new Paint();
  1. 画笔颜色
    paint.setColor(Color.parseColor("#FFFFFF"));

3.设置画笔样式,如果不设置,默认是全部填充(FILL)

   paint.setStyle(Paint.Style.FILL);
画笔样式分三种
  • Paint.Style.STROKE:描边

  • Paint.Style.FILL_AND_STROKE:描边并填充

  • Paint.Style.FILL:填充

4.打开抗锯齿;抗锯齿是依赖于算法的,算法决定抗锯齿的效率,在我们绘制棱角分明的图像时,比如一个矩形、一张位图,我们不需要打开抗锯齿

 paint.setAntiAlias(true);

5.设置笔刷的粗细度

   int linePaintStroke = dp2px(context, 3);
   paint.setStrokeWidth(linePaintStroke);

核心部分

ProgressLineView
package com.advance.yongliu.customlineview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

/**
 * @author YongLiu
 *         date  2019/1/6.
 *         desc:
 */

public class ProgressLineView extends View {
    private Paint paint;
    private int viewWidth;
    private int viewHeight;
    private Paint behindPaint;
    private Paint textPaint;
    private float mPresent;
    private String growthValue = "成长值";
    private String current = "目前";

    public ProgressLineView(Context context) {
        super(context);
        init(context);
    }

    public ProgressLineView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public ProgressLineView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        /**
         * 顶部画笔配置
         * */
        paint = new Paint();
        paint.setColor(Color.parseColor("#FFFFFF"));
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true);
        int linePaintStroke = dp2px(context, 3);
        paint.setStrokeWidth(linePaintStroke);

        /**
         * 底部画笔配置
         * */
        behindPaint = new Paint();
        behindPaint.setColor(Color.parseColor("#33000000"));
        behindPaint.setStyle(Paint.Style.FILL);
        behindPaint.setAntiAlias(true);
        int linePaintStroke1 = dp2px(context, 3);
        behindPaint.setStrokeWidth(linePaintStroke1);

        /**
         * 控件文字画笔配置
         * */
        textPaint = new Paint();
        textPaint.setColor(Color.parseColor("#FFFFFF"));
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setTextSize(16);
        textPaint.setAntiAlias(true);
        int linePaintStroke2 = dp2px(context, 50);
        textPaint.setStrokeWidth(linePaintStroke2);
    }

    /**
     * 设值 - 绘制
     * */
    public void setPresent(float present, String growthValue) {
        this.growthValue = growthValue;
        //动画效果,不适合此处控件
    /*    ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, present).setDuration(2000);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mPresent = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        valueAnimator.start();*/
        mPresent = present;
        //绘制
        invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        /**
         * 获取我们控件的宽、高
         * */
        viewWidth = MeasureSpec.getSize(widthMeasureSpec);
        viewHeight = MeasureSpec.getSize(heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        
        /**
		 * 设置图片,并获取图片宽高  (俩图自行找UI获取)
		 * @params bigBitmap  进度大圆点
		 * @params smallBitmap 首尾小圆点
		 */
        Bitmap bigBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_big_whirte_dot);
        int bitmapWidth = bigBitmap.getWidth();
        int bitmapHeight = bigBitmap.getHeight();
        Bitmap smallBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_small_white_dot);
        int smallWidth = bigBitmap.getWidth();
        int smallHeight = bigBitmap.getHeight();

        //字体宽高
        float text1Width = textPaint.measureText(current);
        float text2Width = textPaint.measureText(growthValue);
        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
        float textHeight = fontMetrics.bottom - fontMetrics.top;

       /**
        * @params mPresent 进度百分比
        * @params stopLine 上层线条展示的区域长度
        * */
        float stopLine = viewWidth * mPresent;
        if (stopLine == 0) {
            stopLine = smallWidth / 2;
        }
        if (mPresent >= 0.95) {
            stopLine = viewWidth - (smallWidth + 20);
        }

        /**
         * 文字间距配置
         * */
        float text1Start = stopLine - text1Width / 2 > 0 ? stopLine - text1Width : 0;
        float text2Start = stopLine - text2Width / 2 > 0 ? stopLine - text2Width : 0;
        if (text1Start <= 0) {
            text1Start = 15;
        }
        if (text2Start <= 0) {
            text2Start = 15;
        }

        if (mPresent != 1) {
            if (text1Start == 15 || text2Start == 15) {
                canvas.drawText(current, text1Start, viewHeight / 2 - textHeight, textPaint);
                canvas.drawText(growthValue, text2Start, viewHeight / 2, textPaint);
            } else {
                canvas.drawText(current, text1Start + smallWidth / 2 + 10, viewHeight / 2 - textHeight, textPaint);
                canvas.drawText(growthValue, text2Start + smallWidth + 10, viewHeight / 2, textPaint);
            }
        } else {
            canvas.drawText(current, viewWidth - text1Width, viewHeight / 2 - textHeight, textPaint);
            canvas.drawText(growthValue, viewWidth - text2Width, viewHeight / 2, textPaint);
        }

        /**
         * 进行绘制!!!   俩条线、首位俩个圆点、一个进度点
         * */
        canvas.drawLine(10, viewHeight / 2 + 40, viewWidth - 10, viewHeight / 2 + 40, behindPaint);
        canvas.drawLine(10 , viewHeight / 2 + 40, stopLine, viewHeight / 2 + 40, paint);
        canvas.drawBitmap(bigBitmap, stopLine, viewHeight / 2 - bitmapHeight / 2 + 40, null);
        canvas.drawBitmap(smallBitmap, 0, viewHeight / 2 - smallHeight / 2 + 42, null);
        canvas.drawBitmap(smallBitmap, viewWidth - smallWidth, viewHeight / 2 - smallHeight / 2 + 42, null);
    }


    private int dp2px(Context context, float dpValue) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}


使用部分

MainActivity
package com.advance.yongliu.customlineview;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ProgressLineView mLineView = findViewById(R.id.line_progress_view);
        TextView mCurrent = findViewById(R.id.tv_current);
        TextView mLast = findViewById(R.id.tv_last);

        /**
         * 传入自定义控件的数据,此处先行设置模拟值(这里一般都是接口返回处理我们进行组装)
         * @params currentData 当前成长值  用于文字显示区域
         * @params newCurrent  此处有公式 newCurrent =  currentData - 上一等级值 ; 因此处上一等级值为0 故直接设置
         * @params newNestData 下一等级值
         * */
        float currentData = Float.parseFloat("20");
        float newCurrent = 20;
        float newNestData = 100;
        mLineView.setPresent(newCurrent / newNestData, "成长值" + Float.valueOf(currentData).intValue());

        mCurrent.setText(String.format("青铜等级:%d", 0));
        mLast.setText(String.format("白银等级:%s", 100));

        /**
         * 参考代码 :目前项目中使用的
         * @params lastLevelValue 上个等级
         * @params nextLevelValue 下个个等级
         *
         * float lastData = Float.parseFloat(lastLevelValue);
         * float nestData = Float.parseFloat(nextLevelValue);
         *
         * float newCurrent = currentData - lastData;
         * float newNestData = nestData - lastData;
         * */
    }
}

MainActivity xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f00"
    android:orientation="vertical"
    tools:context="com.advance.yongliu.customlineview.MainActivity">

    <com.advance.yongliu.customlineview.ProgressLineView
        android:id="@+id/line_progress_view"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="20dp"
        />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/tv_current"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="5dp"
            android:text="当前等级"
            android:textColor="#fff"
            android:textSize="11sp"
            />

        <TextView
            android:id="@+id/tv_last"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="5dp"
            android:layout_marginTop="5dp"
            android:text="下一等级"
            android:textColor="#fff"
            android:textSize="11sp"
            />
    </RelativeLayout>
</LinearLayout>

猜你喜欢

转载自blog.csdn.net/qq_20451879/article/details/87930949
今日推荐