自定义view图形的步骤

本文详细介绍自定义View的基本步骤及方法,包括不同版本的构造方法重写、绘图过程中的核心方法ondraw的实现细节,并展示了如何通过Path和Canvas进行复杂图形绘制,以及如何实现触摸事件监听。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自定义view的=步骤:
自定义view是在版本21之前重写三个方法,版本21之后重写四个方法;
1:创建一个类继承一个view
2:实现里面的三个方法
/////////////////////////////////////////////////////////////////////////////////////////////
重写的三个方法是:
方法一是上下文
public CircleView(Context context){
super (context)
}
方法二是两个参数为:上下文、布局文件
public CircleView(Context context,AttributeSet attrs){
super (context,attrs)
}
方法三三个参数为:上下文、布局文件、布局样式
public CircleView(Context context,AttributeSet attrs,int defstyleAttr){
super (context,attrs,defstyleAttr)
}
方法四参数为: 上下文,布局文件、布局样式、资源文件
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public Myview(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
////////////////////////////////////////////////////////////
////////////////////////////////////////
3: 重写一个ondraw方法,一般是在这个方法里面书写画的图形
里面的实现步骤是:根据canvas得到控件的宽度和高度
在得到圆的半径;
然后在实例化画笔、设置画笔的颜色、设置去调锯齿、设置图形的样式看一下Paint的style,共有3种
Paint.Style.FILL:填充内部(实心)
Paint.Style.FILL_AND_STROKE  :填充内部和描边
Paint.Style.STROKE  :描边(空心)
paint3.setStrokeWidth(10);//定义画笔的宽度
int i4 = Math.min(width, height)/2;//获取圆的半径
//这是画圆的方法四个参数:(参数1宽度的位置,参数二是高度的位置
参数三是得到远的半径,参数四是画笔)
canvas.drawCircle(600,height,i3,paint1);


//重置Paint。
reset()
//设置一些标志,比如抗锯齿,下划线等等。
setFlags(int flags)
//设置抗锯齿,如果不设置,加载位图的时候可能会出现锯齿状的边界,如果设置,边界就会变的稍微有点模糊,锯齿就看不到了。
setAntiAlias(boolean aa)
//设置是否抖动,如果不设置感觉就会有一些僵硬的线条,如果设置图像就会看的更柔和一些,
setDither(boolean dither)
//这个是文本缓存,设置线性文本,如果设置为true就不需要缓存,
setLinearText(boolean linearText)
//设置亚像素,是对文本的一种优化设置,可以让文字看起来更加清晰明显,可以参考一下PC端的控制面板-外观和个性化-调整ClearType文本
setSubpixelText(boolean subpixelText)
//设置文本的下划线
setUnderlineText(boolean underlineText)
//设置文本的删除线
setStrikeThruText(boolean strikeThruText)
//设置文本粗体
setFakeBoldText(boolean fakeBoldText)
//对位图进行滤波处理,如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加快显示 
setFilterBitmap(boolean filter)
//下面这几个就不用说了,上面已经演示过
setStyle(Style style),setStrokeCap(Cap cap),setStrokeJoin(Join join),setTextAlign(Align align),
//设置画笔颜色
setColor(int color)
//设置画笔的透明度[0-255],0是完全透明,255是完全不透明
setAlpha(int a)
//设置画笔颜色,argb形式alpha,red,green,blue每个范围都是[0-255],
setARGB(int a, int r, int g, int b)
//画笔样式为空心时,设置空心画笔的宽度
setStrokeWidth(float width)
//当style为Stroke或StrokeAndFill时设置连接处的倾斜度,这个值必须大于0,看一下演示结果
setStrokeMiter(float miter)
/////////////////////////////////////////////////////////////////////
代码实现
自定义的view方法步骤:
* 画笔的方法
*/
private void initdata() {
mPaint = new Paint();
//定义颜色
mPaint.setColor(Color.GREEN);
//给他样式为空
mPaint.setStyle(Paint.Style.STROKE);
//去锯齿
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(6);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//得到控件的高度和宽度
int height = canvas.getHeight() / 2;
int width = canvas.getWidth()/2;
//得到半径
int i = Math.min(width, height);
Path path0 = new Path();
path0.addCircle(width,height,i,Path.Direction.CCW);
canvas.drawPath(path0,mPaint);
//这是连线的类
Path path = new Path();
//起始点(找到起始点的坐标)
path.moveTo(width-i,height);
//连线定义每个点的位置
path.lineTo(width,height-i);
path.lineTo(width + i, height);
path.lineTo(width, height+ i);
//最后链接
path.close();
//显示
canvas.drawPath(path,mPaint);
///////////////////////////////////////////
//初始化一个连线的类,画的里面的一个正方形
Path path1 = new Path();
//得到起始点的坐标R
path1.moveTo(width-i/2,height-i/2);
//连线定义每个点的位置
path1.lineTo(width-i/2,height+i/2);
path1.lineTo(width+i/2,height+i/2);
path1.lineTo(width+i/2,height-i/2);
//最后的链接
path1.close();
//显示
canvas.drawPath(path1,mPaint);
/////////////////////////////
// DIFFERENCE:之前剪切过除去当前要剪切的区域(蓝色区域)。
path0.op(path,DIFFERENCE);
path.op(path1,DIFFERENCE);
//实例化一个区域并定义
mRegion = new Region(0,0,getWidth(),getHeight());
mRegion1 = new Region(0,0,getWidth(),getHeight());
mRegion2 = new Region(0,0,getWidth(),getHeight());
mRegion.setPath(path0,mRegion);
mRegion1.setPath(path,mRegion1);
mRegion2.setPath(path1,mRegion2);
}
//实现监听的方法
@Override
public boolean onTouchEvent(MotionEvent event) {
//获取点击屏幕的X坐标和Y坐标
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()){
//判断按下的方法
case MotionEvent.ACTION_UP:
//根据区域判断点击的坐标,传个接口
if (mRegion.contains(x,y)) {
mListener.onClick(this);

}
if (mRegion1.contains(x,y)) {
m.onClick(this);
}
if (mRegion2.contains(x,y)) {
j.onClick(this);
}
break;
}
return true;
}

@Override
public void setOnClickListener(OnClickListener l) {
super.setOnClickListener(l);
mListener = l;
}

public void setOnClick(OnClickListener m) {
this.m = m;
}
public void setfang(OnClickListener j){
this.j=j;
}
OnClickListener mListener;
OnClickListener m;
OnClickListener j;
/////////////////////////
在activity里面实现监听就可以了;我们调用的是系统接口
my_view2= (MyHuaYu) findViewById(R.id.m_view);
//实现菱形以外的区域监听
my_view2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"这是圆",Toast.LENGTH_SHORT).show();
}
});
//实现方形形以外的区域监听
my_view2.setOnClick(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"这是菱形",Toast.LENGTH_SHORT).show();
}
});
//实现方形以内的监听
my_view2.setfang(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"这是方形",Toast.LENGTH_SHORT).show();
}
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值