自定义View练习题目整理

一、动态音频播放柱形图

1、效果图:

在这里插入图片描述

2、步骤

(1)、新建自定义View类,继承View
(2)、重写onDraw()方法,使用画笔和画布循环画一定数量的柱形

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

       //画柱形
       for (int i = 0; i < 10; i++){
           float mRandom = (float) Math.random();
           float currentHeight = mRectHeight*mRandom;
          canvas.drawRect((float) (mWidth*0.4/2+mRectWidth * i +offset),currentHeight, (float) (mWidth*0.4/2+mRectWidth*(i+1)),mRectHeight,mPaint1);
       }
       postInvalidateDelayed(800);
   }

(3)、重写onSizeChange()方法,实现柱形的渐变效果

    @Override
   protected void onSizeChanged(int w, int h, int oldw, int oldh) {
       super.onSizeChanged(w, h, oldw, oldh);
       //实现音频柱的渐变效果
       mWidth = getWidth();
       mRectHeight = getHeight();
       mRectWidth = (int) (mWidth*0.6/10);
       mLinearGradient = new LinearGradient(
               0,0,mRectWidth,mRectHeight,Color.YELLOW,Color.BLUE, Shader.TileMode.CLAMP);
       mPaint1.setShader(mLinearGradient);
   }

(4)、在适合的xml布局文件中引入即可

<com.example.test.MyView1
        android:id="@+id/myView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/text"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

附:全部代码如下:

package com.example.test;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.Nullable;

public class MyView1 extends View {

   Paint mPaint1;  //画笔
   int mWidth = 200;
   int mHeight = 1000;
   int mRectWidth = 30; //柱形的宽度
   int mRectHeight = 200; //柱形的高度
   int offset = 5; //柱形之间的距离

   LinearGradient mLinearGradient;

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

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

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

   private void init(){
   	   //初始化画笔和画笔的颜色、样式等
       mPaint1 = new Paint();
       mPaint1.setColor(getResources().getColor(R.color.purple_200));
   }

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

       //画柱形
       for (int i = 0; i < 10; i++){
           float mRandom = (float) Math.random();
           float currentHeight = mRectHeight*mRandom;
          canvas.drawRect((float) (mWidth*0.4/2+mRectWidth * i +offset),currentHeight, (float) (mWidth*0.4/2+mRectWidth*(i+1)),mRectHeight,mPaint1);
       }
       postInvalidateDelayed(800);
   }

   @Override
   protected void onSizeChanged(int w, int h, int oldw, int oldh) {
       super.onSizeChanged(w, h, oldw, oldh);
       //实现音频柱的渐变效果
       mWidth = getWidth();
       mRectHeight = getHeight();
       mRectWidth = (int) (mWidth*0.6/10);
       mLinearGradient = new LinearGradient(
               0,0,mRectWidth,mRectHeight,Color.YELLOW,Color.BLUE, Shader.TileMode.CLAMP);
       mPaint1.setShader(mLinearGradient);
   }
}

二、自定义大小的圆形

1、效果图

一个圆形

2、步骤

(1)新建自定义View类,继承View
(2)可设置自定义属性

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //自定义属性
        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.MyView);
        mColor = a.getColor(R.styleable.MyView_circle_color,Color.RED);
        a.recycle();
        init();
    }

values文件下面新建attrs.xml,可设置颜色,后续可设置给画笔

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //自定义属性
        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.MyView);
        mColor = a.getColor(R.styleable.MyView_circle_color,Color.RED);
        a.recycle();
        init();
    }

(3)重写onMeasure(),自定义绘制大小

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //宽测量模式
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        //宽测量大小
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        //高测量模式
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        //高测量大小
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(200,200);
        }else if (widthSpecMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(200,heightSpecSize);
        }else if (heightSpecMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(widthSpecSize,200);
        }else{
            setMeasuredDimension(widthMeasureSpec,heightMeasureSpec);
        }
    }

(4)重写onDraw()方法画圆形

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = getWidth()-getPaddingLeft()-getPaddingLeft();
        int height = getHeight()-getPaddingLeft()-getPaddingLeft();
        int radius = Math.min(width,height)/2;
        canvas.drawCircle((float) width/2+getPaddingLeft(),(float) height/2+getPaddingLeft(),radius,paint);
    }

(5)相应地方调用需注意设置wrap_content,因为想实现重写onDraw方法中的效果,需要自己支持wrap_content,并且padding也需要自己处理。

<com.example.test.MyView
        android:id="@+id/myView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        app:layout_constraintTop_toBottomOf="@+id/text"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

附:全部代码

package com.example.test;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;

public class MyView extends View {

    public int mColor = Color.RED;
    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

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

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

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //自定义属性
        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.MyView);
        mColor = a.getColor(R.styleable.MyView_circle_color,Color.RED);
        a.recycle();
        init();
    }

    //初始化画笔
    private void init(){
        paint.setColor(mColor);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //宽测量模式
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        //宽测量大小
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        //高测量模式
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        //高测量大小
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(200,200);
        }else if (widthSpecMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(200,heightSpecSize);
        }else if (heightSpecMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(widthSpecSize,200);
        }else{
            setMeasuredDimension(widthMeasureSpec,heightMeasureSpec);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = getWidth()-getPaddingLeft()-getPaddingLeft();
        int height = getHeight()-getPaddingLeft()-getPaddingLeft();
        int radius = Math.min(width,height)/2;
        canvas.drawCircle((float) width/2+getPaddingLeft(),(float) height/2+getPaddingLeft(),radius,paint);
    }

}

猜你喜欢

转载自blog.csdn.net/qq_46269365/article/details/129198883