1.概念
android中组件必须是View的直接子类或间接子类,其中View有一个ViewGroup的子类,用于定义容器(FrameLayout等)
如果组件中还有子组件,就一定是从从ViewGroup类继承,否则从View类继承 View类就相当于控件的上帝一样,只要是自定义控件,要么是View'的直接子类,要么就是View的间接子类
View类定义组件相关的通用功能, 自定义控件一定会和View产生关系,所以View使我们开发者,必须要详细理解的类
2.自定义View的三种形式
1.扩展式自定义View 继承自Android原声特定的View:如Textview,ImageView等,我们通过重写OnDraw等回调方法进行扩展,从而实现我
们想要的功能或者形式
注意:该方法实现的自定义View控件,不需要自己支持wrap_content和padding(因为继承的View已经实现)
2.组合式自定义View 继承自ViewGroup的子View(LinerLayout,RelativityLayout等)当某种效果看起来像几种View组合在一起实现的时候,我们就可以用这种方法
注意:该方法实现的自定义View控件,不需要自己处理ViewGroup的测量和布局至两个功能(因为以及估值好了)
3.完全自定义View继承自View(Android中所有控件的基类),通常实现一些不方便布局的组合方式,需要静态或动态的显示一些不规则的控件或图形
注意:该方法实现的自定义View控件,需要自己支持wrap_content和padding(完成从无到有,系统无法确定,必须自己操作)
3.完全自定义View
步骤:
0.
类要继承View空间的基类
1.重写构造方法
2.重写onMeasure方法
3.重写OnDraw方法
4.使用自定义控件
代码如下:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
//
步骤
0.
类要继承
View
空间的基类
public class MyView extends View {
// 步骤 1. 重写构造方法
// 在代码中添加我们自定义 View 时 , 所调用的构造方法
public MyView(Context context) {
super(context);
}
// 在布局 XML 文件中添加自定义控件时 , 所调用的方法 , 多了一个参数 AttributeSet
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
// 这个方法一半我们用不到 , 不是系统调用的
// 需要我们显示调用 , 并给 defStyleAttr 传值 , 多了一个 defStyleAttr 参数
// 引用 style 资源属性是 , 也就是我们可以在 style 中自定义 View 定义一个默认的属性样式
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// 步骤 2. 重写 onMeasure 方法
// 测量 View 控件 , 决定控件在手机所占未知的大小
@Override
protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
// 步骤 3. 重写 OnDraw 方法
// 绘制了控件 , 决定以控件呈现的样式 , 参数就是一个画布 , 可以直接使用
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 定义一个画笔
Paint paint = new Paint();
// 设置抗锯齿
paint.setAntiAlias( true);
// 设置画笔的宽度
paint.setStrokeWidth( 2);
// 设置画笔的颜色
paint.setColor(Color. BLUE);
public class MyView extends View {
// 步骤 1. 重写构造方法
// 在代码中添加我们自定义 View 时 , 所调用的构造方法
public MyView(Context context) {
super(context);
}
// 在布局 XML 文件中添加自定义控件时 , 所调用的方法 , 多了一个参数 AttributeSet
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
// 这个方法一半我们用不到 , 不是系统调用的
// 需要我们显示调用 , 并给 defStyleAttr 传值 , 多了一个 defStyleAttr 参数
// 引用 style 资源属性是 , 也就是我们可以在 style 中自定义 View 定义一个默认的属性样式
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// 步骤 2. 重写 onMeasure 方法
// 测量 View 控件 , 决定控件在手机所占未知的大小
@Override
protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
// 步骤 3. 重写 OnDraw 方法
// 绘制了控件 , 决定以控件呈现的样式 , 参数就是一个画布 , 可以直接使用
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 定义一个画笔
Paint paint = new Paint();
// 设置抗锯齿
paint.setAntiAlias( true);
// 设置画笔的宽度
paint.setStrokeWidth( 2);
// 设置画笔的颜色
paint.setColor(Color. BLUE);
//设置画笔的样式 STROKE(空心) FILL(实心)
paint.setStyle(Paint.Style.
STROKE);
// 设置画笔所绘制的文本字体大小
paint.setTextSize( 35);
// 设置画笔所绘制的文本字体大小
paint.setTextSize( 35);
canvas.drawCircle(300,150,80,paint);
//
绘制一个文本
//参数1:要画的文本, 参数2,3画的起始坐标 4为画笔
canvas.drawText("666",300,400,paint);
//绘制一个直线,参数1和2起点坐标 参数3和4终点坐标 5为画笔
canvas.drawLine(300,300,300,500,paint);
//绘制三角形
//绘制路径,首先创建路径对象
Path path = new Path();
//设置一个起点
path.moveTo(300,0);
//画线到该点
path.lineTo(0,300);
//画线到该点
path.lineTo(600,300);
//将路线封闭 形成三角形
path.close();
//
开始画 参数
1 path
对象 参数
2
画笔
canvas.drawPath(path,paint);
}
}
}
4.布局文件
<
RelativeLayout
xmlns: android = "http://schemas.android.com/apk/res/android"
xmlns: tools = "http://schemas.android.com/tools"
android :layout_width= "match_parent"
android :layout_height= "match_parent"
tools :context= "com.zhiyuan3g.customviewdemo.MainActivity">
< com.zhiyuan3g.customviewdemo.MyView
android :layout_width= "match_parent"
android :layout_height= "match_parent"/>
xmlns: android = "http://schemas.android.com/apk/res/android"
xmlns: tools = "http://schemas.android.com/tools"
android :layout_width= "match_parent"
android :layout_height= "match_parent"
tools :context= "com.zhiyuan3g.customviewdemo.MainActivity">
< com.zhiyuan3g.customviewdemo.MyView
android :layout_width= "match_parent"
android :layout_height= "match_parent"/>
</RelativeLayout>
5.程序结果