对于自定义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的三个构造函数
public MyView(Context context) {
super(context);
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);
效果如下:

五、相关注意事项
(一)注意三种构造函数的调用情况 ,第一和第二类的构造函数是比较常用的,为了避免出现不必要的与构造函数相关的错误,建议最好把三种构造函数都写上;
(二)注意onDraw()方法在每次绘制的时候都会调用,如果动态绘制的话,onDraw会多次调用,因此建议不要在onDraw()方法中进行画布画笔的相关初始化,通常将这些初始化放到构造函数中,记得三个构造函数都要加上;
(三)注意画笔的颜色与背景的搭配。 曾因为将画笔设置为白色而背景颜色没有设置,即默认为白色,导致自定义VIew没有显示出来,后来花了一个上午的时间尝试断点调试、查看官方文档、日志打印查询等方法来排查问题都还是一无所获,直到我看到了Paint.setColor(Color.White),然后将background设置为 #000000(黑色),发现原来是画笔颜色和背景颜色一样导致的结果(刻骨铭心)
一、简述对于自定义View的实现,Canvas和Paint两类是很有用的。 这两个类是 android.graphics 包下的两个类,Canvas是画布,Paint是画笔,通过这两者结合一起,就可以绘制出自己需要的View,然后将View加入到布局 xml 中或者在 Java 代码中引用即可。二、基本步骤(一)创建一个自定义的MyView继承View (二)创建MyView的三个...
ViewView代表屏幕的一个矩形区域,负责绘制这个区域和这个区域的事件处理
View的坐标位置由6个方法来获取View左方的距离getLeft,View右方的距离getRight,View上方的距离getTop,View下方的距离getBottom,宽度getWidth,高度getHeight
实例化1.构造方法1).View(context);在java代码中使用的构造器,没有设置任何值,只有
摘要 Android中使用图形处理引擎,2D部分是android SDK内部自己提供,3D部分是用Open GL ES 1.0。今天我们主要要了解的是2D相关的,如果你想看3D的话那么可以跳过这篇文章。 大部分2D使用的api都在android.graphics和android.graphics.drawable包中。他们提供了图
Android中使用图形处理引擎,2D部分是android
setColor(int),设置画笔的颜色
setAlpha(int),设置画笔的透明度
setARGB(int a, int r, int g, int b),设置画笔的颜色,a代表透明度,r,g,b代表颜色值
setAntiAlias(boolean),设置是否使用抗锯齿功能,设置后会平滑一些
setDither(boolean),设定是否使用图像抖动处理,设置后图像更加清晰
setStyle(Style),设置画笔的风格
Style.FILL,实心
Style.FILL_A