ondraw() 和dispatchdraw()的区别 .

本文详细解析了Android中View和ViewGroup的绘制流程,包括如何通过onDraw()方法绘制自身内容,以及如何通过dispatchDraw()方法绘制子View。特别关注了背景Drawable的设置及其对View尺寸的影响。

绘制VIew本身的内容,通过调用View.onDraw(canvas)函数实现

绘制自己的孩子通过dispatchDraw(canvas)实现

View组件的绘制会调用draw(Canvas canvas)方法,draw过程中主要是先画Drawable背景,对 drawable调用setBounds()然后是draw(Canvas c)方法.有点注意的是背景drawable的实际大小会影响view组件的大小,drawable的实际大小通过getIntrinsicWidth()和getIntrinsicHeight()获取,当背景比较大时view组件大小等于背景drawable的大小

画完背景后,draw过程会调用onDraw(Canvas canvas)方法,然后就是dispatchDraw(Canvas canvas)方法, dispatchDraw()主要是分发给子组件进行绘制,我们通常定制组件的时候重写的是onDraw()方法。值得注意的是ViewGroup容器组件的绘制,当它没有背景时直接调用的是dispatchDraw()方法, 而绕过了draw()方法,当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用。因此要在ViewGroup上绘制东西的时候往往重写的是dispatchDraw()方法而不是onDraw()方法,或者自定制一个Drawable,重写它的draw(Canvas c)和 getIntrinsicWidth(),

getIntrinsicHeight()方法,然后设为背景。

参见http://blog.youkuaiyun.com/czh0766/archive/2010/08/05/5790295.aspx

绘制VIew本身的内容,通过调用View.onDraw(canvas)函数实现

绘制自己的孩子通过dispatchDraw(canvas)实现

View组件的绘制会调用draw(Canvas canvas)方法,draw过程中主要是先画Drawable背景,对 drawable调用setBounds()然后是draw(Canvas c)方法.有点注意的是背景drawable的实际大小会影响view组件的大小,drawable的实际大小通过getIntrinsicWidth()和getIntrinsicHeight()获取,当背景比较大时view组件大小等于背景drawable的大小

画完背景后,draw过程会调用onDraw(Canvas canvas)方法,然后就是dispatchDraw(Canvas canvas)方法, dispatchDraw()主要是分发给子组件进行绘制,我们通常定制组件的时候重写的是onDraw()方法。值得注意的是ViewGroup容器组件的绘制,当它没有背景时直接调用的是dispatchDraw()方法, 而绕过了draw()方法,当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用。因此要在ViewGroup上绘制东西的时候往往重写的是dispatchDraw()方法而不是onDraw()方法,或者自定制一个Drawable,重写它的draw(Canvas c)和 getIntrinsicWidth(),

getIntrinsicHeight()方法,然后设为背景。

参见http://blog.youkuaiyun.com/czh0766/archive/2010/08/05/5790295.aspx

2025-09-27 22:02:59.763 8961-8961/cn.edu.xjau.addressbook E/AndroidRuntime: FATAL EXCEPTION: main Process: cn.edu.xjau.addressbook, PID: 8961 java.lang.RuntimeException: Canvas: trying to draw too large(115605504bytes) bitmap. at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:260) at android.graphics.Canvas.drawBitmap(Canvas.java:1415) at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:545) at android.widget.TextView.onDraw(TextView.java:5745) at android.view.View.draw(View.java:17071) at android.view.View.updateDisplayListIfDirty(View.java:16053) at android.view.View.draw(View.java:16837) at android.view.ViewGroup.drawChild(ViewGroup.java:3764) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) at android.view.View.updateDisplayListIfDirty(View.java:16048) at android.view.View.draw(View.java:16837) at android.view.ViewGroup.drawChild(ViewGroup.java:3764) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) at android.view.View.updateDisplayListIfDirty(View.java:16048) at android.view.View.draw(View.java:16837) at android.view.ViewGroup.drawChild(ViewGroup.java:3764) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) at android.view.View.draw(View.java:17074) at android.view.View.updateDisplayListIfDirty(View.java:16053) at android.view.View.draw(View.java:16837) at android.view.ViewGroup.drawChild(ViewGroup.java:3764) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) at android.view.View.updateDisplayListIfDirty(View.java:16048) at android.view.View.draw(View.java:16837) at android.view.ViewGroup.drawChild(ViewGroup.java:3764) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) at android.view.View.updateDisplayListIfDirty(View.java:16048) at android.view.View.draw(View.java:16837) at android.view.ViewGroup.drawChild(ViewGroup.java:3764) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) at android.view.View.updateDisplayListIfDirty(View.java:16048) at android.view.View.draw(View.java:16837) at android.view.ViewGroup.drawChild(ViewGroup.java:3764) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) at android.view.View.draw(View.java:17074) at com.android.internal.policy.DecorView.draw(DecorView.java:751) at android.view.View.updateDisplayListIfDirty(View.java:16053) at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:656) at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:662) at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:770) at android.view.ViewRootImpl.draw(ViewRootImpl.java:2796) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2604) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2211) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1246) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6301) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871) at android.view.Choreographer.doCallbacks(Choreographer.java:683) at android.view.Choreographer.doFrame(Choreographer.java:619) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6077) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) 这样报错怎么办
09-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值