失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android自定义View基本步骤

Android自定义View基本步骤

时间:2023-07-17 12:04:15

相关推荐

Android自定义View基本步骤

一.自定义属性

1.在res下的values下面新建attrs.xml

2.在布局中使用,声明命名空间

3.在自定义View构造方法中通过TypedArray获取属性

4.必须回收 array.recycle();

二.重写onMeasure()方法

//widthMeasureSpec : 一个32位的值,会包含两个信息: //模式:前2位;对应的值:后30位 // 获取宽高的模式 int widthMode = MeasureSpec.getMode(widthMeasureSpec); // 获取前两位 int heightMode = MeasureSpec.getMode(heightMeasureSpec); // 获取宽高的值 int widthSize = MeasureSpec.getSize(widthMeasureSpec); // 获取后面30位 int heightSize = MeasureSpec.getSize(heightMeasureSpec);

MeasureSpec.AT_MOST : 在布局中指定了wrap_content

MeasureSpec.EXACTLY : 在不居中指定了确切的值 100dp match_parent fill_parent

MeasureSpec.UNSPECIFIED : 尽可能的大,很少能用到。ListView , ScrollView 在测量子布局的时候会用UNSPECIFIED 。ScrollView + ListView 会显示不全问题

三.重写onDraw(canvas)

常用方法:

canvas.drawText();//画文本

canvas.drawArc();//画弧

canvas.drawCircle();//画圆

canvas.drawBitmap();

canvas.drawLine();canvas.drawLines();

canvas.drawPath();

canvas.drawRect();canvas.drawRoundRect();

canvas.drawOval();

canvas.drawPoint();

问题:自定义view时继承LinearLayout能不能显示效果?不能,默认的ViewGroup不会调用onDraw方法,为什么?

draw(Canvas canvas)方法中,采用模板设计:

if (!dirtyOpaque) onDraw(canvas);dispatchDraw(canvas);onDrawForeground(canvas);

dirtyOpaque是false才执行,其实就是由privateFlags -> mPrivateFlags的值决定

final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE && (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);

mPrivateFlags 到底是怎么赋值的?在View的构造函数中调用 computeOpaqueFlags

protected void computeOpaqueFlags() {if (mBackground != null && mBackground.getOpacity() == PixelFormat.OPAQUE) {mPrivateFlags |= PFLAG_OPAQUE_BACKGROUND;} else {mPrivateFlags &= ~PFLAG_OPAQUE_BACKGROUND;}final int flags = mViewFlags;if (((flags & SCROLLBARS_VERTICAL) == 0 && (flags & SCROLLBARS_HORIZONTAL) == 0) ||(flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_INSIDE_OVERLAY ||(flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_OUTSIDE_OVERLAY) {mPrivateFlags |= PFLAG_OPAQUE_SCROLLBARS;} else {mPrivateFlags &= ~PFLAG_OPAQUE_SCROLLBARS;}}

在ViewGroup的initViewGroup方法中:

private void initViewGroup() {// ViewGroup doesn't draw by defaultif (!debugDraw()) {setFlags(WILL_NOT_DRAW, DRAW_MASK);}}

这里会使mPrivateFlags重新赋值,导致dirtyOpaque为true,最终不执行onDraw方法

如何解决? 思路:改变 mPrivateFlags

1.在自定义View构造方法中调用一下方法,二选一即可

(1).setBackgroundColor(Color.TRANSPARENT);

(2).setWillNotDraw(false);

2.调用dispatchDraw()

如果觉得《Android自定义View基本步骤》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。