美文网首页
Android_自定义控件_进度控价

Android_自定义控件_进度控价

作者: 书虫大王X | 来源:发表于2019-10-30 22:29 被阅读0次

要实现的功能:

功能 代码流程

画贝塞尔曲线:

//画贝塞尔曲线

public class waveView extends View {

    private ValueAnimator va;
    private Paint mPaint;
    private Path mPath;
//    屏幕密度
    int  density = (int)(getResources().getDisplayMetrics().density);
//    波长
    private int waveLength = 200*density;
//    波峰
    private int waveCrest = 70*density;
//    动画起始点的偏移值
    private int speed;
    private int lineColor = Color.BLACK;
    private int lineSize = 10;


    public waveView(Context context) {
        this(context,null);
    }

    public waveView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(lineColor);
        mPaint.setStrokeWidth(lineSize);
        mPaint.setStyle(Paint.Style.STROKE);

    }
  @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        startWave();
    }

    private void startWave(){

        va = ValueAnimator.ofInt(0,waveLength);
        va.setDuration(500);
        va.setRepeatCount(ValueAnimator.INFINITE);
        va.setRepeatMode(ValueAnimator.RESTART);
        va.setInterpolator(new LinearInterpolator());
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
//                获取当前值
                speed = (int)valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        va.start();
    }
    public void stopWave(){
        if (va != null) {
            va.cancel();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mPath = new Path();
//        计算有几个完整的周期
        int count = getWidth()/waveLength;
//        设置wave的起始点
        mPath.moveTo(-waveLength+speed,getHeight()/2);
//        获取中垂线
        int center = (int)getPivotY();
//        确定曲线的路径
        for(int start = -waveLength+speed;start < getWidth();start += waveLength){
            mPath.cubicTo(start,center,start + waveLength/4,center-waveCrest,start + waveLength/2,center);
            mPath.cubicTo(start + waveLength/2,center,start + waveLength*3/4,center+waveCrest,start + waveLength,center);
        }

        canvas.drawPath(mPath,mPaint);
    }

    public void setLineColor(int lineColor) {
        this.lineColor = lineColor;
        mPaint.setColor(lineColor);
    }

    public void setLineSize(int lineSize) {
        this.lineSize = lineSize;
        mPaint.setStrokeWidth(lineSize);
    }

    public void setWaveCrest(int waveCrest) {
        this.waveCrest = waveCrest;
    }

    public void setWaveLength(int waveLength) {
        this.waveLength = waveLength;
    }
}

画百分数文本和外圈圆环:

public class circleView extends View {

//    控件的外圈
    Paint circlePaint;
//    控件的百分数
    Paint textPaint;
    private int lineWidth = 5;
    private int lineColor = Color.BLACK;
    private int textColor = Color.GRAY;
    private int textSize = 50;
    private String text = "100%";
//    百分数的进度
    private float progress;
    //文字与中心线的距离
    private int centerSpace;


    public circleView(Context context) {
        this(context,null);
    }

    public circleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePaint.setColor(lineColor);
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setStrokeWidth(lineWidth);

        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setColor(textColor);
        textPaint.setStyle(Paint.Style.STROKE);
        textPaint.setTextSize(textSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int radius = Math.min(getWidth(),getHeight()/2) - 2*lineWidth;
//        getPivotX 获取中心点
        canvas.drawCircle(getPivotX(),getPivotY(),radius,circlePaint);

        text = (int)(progress)+"%";
//        计算文本的宽度
        int width = (int) textPaint.measureText(text);
//        获取文字矩阵
        Paint.FontMetricsInt fn = textPaint.getFontMetricsInt();
        canvas.drawText(text,getPivotX() - width/2,getPivotY() + (-fn.ascent)/2+centerSpace,textPaint);
    }


//    定义一系列的setget方法,供外部对控件属性进行设置
    public void setLineColor(int lineColor) {
        this.lineColor = lineColor;
        circlePaint.setColor(lineColor);
    }

    public void setLineWidth(int lineWidth) {
        this.lineWidth = lineWidth;
        circlePaint.setStrokeWidth(lineWidth);
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setTextColor(int textColor) {
        this.textColor = textColor;
        textPaint.setColor(textColor);
    }

    public void setTextSize(int textSize) {
        this.textSize = textSize;
        textPaint.setStrokeWidth(textSize);
    }

    public void setProgress(float progress) {
        this.progress = progress;
        if (this.progress >= 100) {
            this.progress = 100;
        }
        invalidate();
    }

    public float getProgress() {
        return progress;
    }

    public void setCenterSpace(int centerSpace) {
        this.centerSpace = centerSpace;
    }
}

继承viewGroup承载两个视图:

public class waveLodingView extends ViewGroup {

//    文本的进程
    private float progress;
    circleView cv;
    waveView wv;

    public waveLodingView(Context context) {
        this(context,null);
    }

    public waveLodingView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

//    viewGroup中,通过子视图来确定容器的尺寸(权力大过xml中的布局)
//    1.先调用这个函数测量控件的尺寸
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

//    3.在这里对控件进行布局
    //    对所有子视图进行布局
//    i:left   i1:top  i2:right i3:button
    @Override
    protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
        cv = new circleView(getContext());
        cv.setLineColor(Color.RED);
        cv.setLineWidth(40);
        cv.setCenterSpace(-80);
        cv.layout(0,0,getWidth(),getHeight());
        addView(cv);

        wv = new waveView(getContext());
        wv.setWaveCrest(30);
        wv.setWaveLength(100);
        wv.setLineColor(Color.RED);
        wv.layout(getWidth()/4,getHeight()/2-30,getWidth()*3/4,getHeight()/2+30);
        addView(wv);
    }

//    2.在这里控件的尺寸已经确定
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    public void setProgress(float progress) {
        this.progress = progress;
        cv.setProgress(progress);
        if (progress >= 100) {
            wv.stopWave();
        }
    }
    public float getProgress() {
        return progress;
    }
}

在xml创建waveLodingView 视图:

   <xn.ky.a1027_zdy_1.waveLodingView
       android:id="@+id/load"
       android:layout_width="300dp"
       android:layout_height="300dp"
       android:layout_centerInParent="true">
   </xn.ky.a1027_zdy_1.waveLodingView>

在MainActivity中实现waveLodingView 的onTouch方法:

public class MainActivity extends AppCompatActivity {

    waveLodingView lodingView;

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

        lodingView = findViewById(R.id.load);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN){

            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    runOnUiThread(new Runnable() {
//                        将任务抛到主线程
                        @Override
                        public void run() {
                            lodingView.setProgress(lodingView.getProgress() + 5);
                        }
                    });

                }
            },0,100);
        }
        return true;
    }
}
成果展示

相关文章

网友评论

      本文标题:Android_自定义控件_进度控价

      本文链接:https://www.haomeiwen.com/subject/siwavctx.html