一、简述
对于自定义View的实现,Canvas和Paint两类是很有用的。
这两个类是 android.graphics 包下的两个类,Canvas是画布,Paint是画笔,通过这两者结合一起,就可以绘制出自己需要的View,然后将View加入到布局 xml 中或者在 Java 代码中引用即可。
二、基本步骤
(一)创建一个自定义的MyView继承View
(二)创建MyView的三个构造方法
- MyView(Context context)
- MyView(Context context,AttributeSet attributeSet)
- MyView(Context context, AttributeSet attributeSet,int defStyleAttr)
(三)重写View.onDraw()方法,添加自己的绘制逻辑
(四)在Java代码中引用或者加入到XML布局中
三、具体步骤
(一)创建一个自定义MyView继承View
public class MyView extends View {
}
(二)创建MyView的三个构造函数
//当Java代码中创建MyView时调用,如setContentView(new MyView(this))
public MyView(Context context) {
super(context);
}
//当在XML中引入MyView时候调用
public MyView(Context context, AttributeSet attributeSet)
{
super(context,attributeSet);
}
//这个构造函数一般不会主动调用
public MyView(Context context,AttributeSet attributeSet,int defStyleAttr)
{
super(context,attributeSet,defStyleAttr);
}
Tips:注意三个构造函数的区别,在不同的情况调用不同的构造函数
(三)重写View.onDraw()方法
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//这里添加自己的绘制逻辑
}
(四)在Java代码中引用或者加入到XML布局中
1、 在Java代码中引用
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
}
2、在XML布局中引入
XML的布局 activity_main
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<com.example.hasee.clockviewdemo.MyView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
Java中加载布局activity_mian
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
四、实例(画一个圆)
完整代码如下:
自定义MyView部分
package com.example.hasee.clockviewdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class MyView extends View {
private Paint mPaint = new Paint();
/*三种构造方法*/
public MyView(Context context) {
super(context);
Log.v("MyView","构造函数1 被调用");
init();
}
public MyView(Context context, AttributeSet attributeSet)
{
super(context,attributeSet);
Log.v("MyView","构造函数2 被调用");
init();
}
public MyView(Context context,AttributeSet attributeSet,int defStyleAttr)
{
super(context,attributeSet,defStyleAttr);
Log.v("MyView","构造函数3 被调用");
init();
}
//实现绘制的方法
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//获取控件的宽高
int width = getWidth();
int height = getHeight();
//设置半径
int raius = Math.min(width,height)/2;
//画线
canvas.drawLine(10,10,100,100,mPaint);
//画圆
canvas.drawCircle(width/2,height/2,raidus,mPaint);
canvas.drawCircle(100,100,20,mPaint);
Log.v("MyView","onDraw() 被调用");
}
//初始化画笔相关设置
public void init()
{
//抗锯齿
mPaint.setAntiAlias(true);
//画笔宽度
mPaint.setStrokeWidth(2f);
//画笔颜色
mPaint.setColor(Color.WHITE);
//画笔填充类型
mPaint.setStyle(Paint.Style.STROKE);
Log.v("MyView","init() 被调用,画笔初始化成功");
}
}
XML布局activity_main.xml部分(使用XML布局中引入的方式引入MyView)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<com.example.hasee.clockviewdemo.MyView
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="#000000"/>
</RelativeLayout>
MainActivity部分
package com.example.hasee.clockviewdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
效果如下: