android-cn / android-discuss

Android 问题交流讨论坛, 微信公众号:codekk, 网站:
https://github.com/android-cn/android-discuss/issues
Apache License 2.0
4.08k stars 537 forks source link

Android中canvas坐标,canvas剪切区的理解 #136

Open ttgdz opened 9 years ago

ttgdz commented 9 years ago

对于view 而言,都有scrollX,ScrollY属性,这个属性在Android 绘画的时候computScroll会用到,那么我想问的是当scroll发生改变的时候,比如一个LinearLayout用一个scroller去改变它的scrollY,这样子LinearLayout的scrollY改变了,那么在drawChild的时候LinearLayout的canvas坐标也改变了,是否因此会逐级改变linearlayout下子view的绘画canvas的原点坐标,因此改变子view的canvas剪切区?已经做过实验,子view的剪切区并没有改变,但是我相信所有的子view的坐标原点都是随linearlayout的scroll改变而改变的,能否说一下Android 中canvas坐标原点的变换,剪切区的变换?

goceancx commented 9 years ago

我的理解是根View像是一张很大的白纸,手机屏幕就是白纸上面的一小块透明的镜子,白纸的不动的,scrollX,scrollY的改变反应了镜子在白纸上面的移动,因此,各种视图相对于白纸的top,left的坐标是不会变的.当在子View中的onDraw方法中进行画图时,由于已经经过layout这个步骤了,因此,onDraw中的canvas的四个点坐标就是(0,0,getwidth,getheight).好吧.我知道了就这么多了.

ttgdz commented 9 years ago

实际上canvas原点坐标是会改变的,随着scroll值得改变,但是clip bound 并没有改变(相对整个窗口上面),只是canvas原点坐标改了,bound的整个区域的坐标值改了。viewgroup的scroll改变反映到child view 子view的canvas原点的改变,所以scroll的时候可以看见子view内容会滑到不同位置,在这个过程中(draw child函数中)viewgroup 通过quickReject拒绝那些已经超出了viewgroup剪切区范围的child view,比较值只是child 的layout的区域和当前viewgroup的剪切区,在这里并没有去计算子view 的scroll值,因为在这个父组件canvas的原点之下,子view的剪切区就是布局区域,即使子viewscroll的剪切区在子view的canvas原点下不同(剪切区在窗口整体上就是那段区域,只是在local coordinate 下坐标显示的不同而已),但是在父组件的canvas原点下一直是layout区域,以上是我几天对于scroll的研究(剪切区在整体上(global coordinate)都是layout区域),scroll只是因为translate改变了canvas原点坐标的位置,导致各种canvas draw操作在不同位置。剪切区的大小不变,一直是layout的大小,剪切区的坐标会随着view的scroll而改变。