View[2] left、top、right、bottom
2017-08-28 17:59
337 查看
【参考链接】
《开发艺术探索》P190
View的长宽及其在父ViewGroup中的位置
Log.e("shadowfaxghh","top="+tv.getTop()+"
left="+tv.getLeft()+"
right="+tv.getRight()+"
bottom="+tv.getBottom());
像setLayoutParams()、属性动画等,因其内部也是在调用requestLayout(),所以也可以实现功能。
其执行流程见《requestLayout()、invalidate()》
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)tv.getLayoutParams();
layoutParams.width=100;
layoutParams.height=100;
layoutParams.leftMargin=100;
layoutParams.topMargin=100;
tv.requestLayout();
// tv.setLayoutParams(layoutParams);
其执行流程是,会进行layout(),然后再执行一次performTraversals,但是此时mLayoutRequested=false,所以此次performTraversals并不会执行measure()、layout(),只会执行draw()。
因此,它有个优点是,可以避开父ViewGroup的布局约束,自由放置位置。但是也有个缺点是,因为缺少了measure(),所以如果draw()时需要用到measure()时产生的辅助数据,则会导致draw()效果异常。
所以可以用它来改变View的位置,但尽量不要用来改变View的大小。
tv.layout(100,100,200,200);
绘制异常:
只绘制出了一行,正常应该同上面一样绘制出两行,这是因为在measure()时会计算好绘制行数(查看源码可知是保存在一个Layout类型的成员变量中),这里直接使用旧的绘制行数,所以绘制异常。
避开布局约束、自由放置位置:
3个TextView是放在一个LinearLayout中,改变中间这个TextView,并没有影响到下面的TextView
不过在《开发艺术探索》中,也讲了几种方法用于在不同时刻获取某个View的长宽和位置,但是除了ViewTreeObserver,个人感觉都很纠结。仅在此记录一下,遇到实际情况再实际选择使用
View.measure()
Activity.onWindowFocusChanged()
ViewTreeObserver
View.post()
通过修改他们也能够改变View的长宽及其在父ViewGroup中的位置
但是却没有改变left\top\right\bottom,也没有引发重新onDraw()
所以现在位置已经不能单纯用left\top\right\bottom来表示了,只能算是View布局完成以后的初始位置。
《开发艺术探索》P190
View的长宽及其在父ViewGroup中的位置
什么时候才能获取的到?
从《Activity、Window、View执行流程概述[2]》中可知,只有在View执行了它自身的layout()及其中的setFrame()以后,才能确定它的大小及在父ViewGroup中的位置。如何获取?
View提供了getLeft()、getTop()、getRight()、getBottom()方法来获取自身的四个点相对于父ViewGroup的距离,通过他们可以知道长宽和位置。Log.e("shadowfaxghh","top="+tv.getTop()+"
left="+tv.getLeft()+"
right="+tv.getRight()+"
bottom="+tv.getBottom());
如何改变?
严格来说,是无法自由改变View在其父ViewGroup中的位置的。因为其需要服从父ViewGroup的布局规则的约束。requestLayout()
可以修改View的布局参数LayoutParams,然后使用requestLayout()使其生效。像setLayoutParams()、属性动画等,因其内部也是在调用requestLayout(),所以也可以实现功能。
其执行流程见《requestLayout()、invalidate()》
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)tv.getLayoutParams();
layoutParams.width=100;
layoutParams.height=100;
layoutParams.leftMargin=100;
layoutParams.topMargin=100;
tv.requestLayout();
// tv.setLayoutParams(layoutParams);
关于layout()方法
也可以直接调用layout()方法来改变View在其父ViewGroup中的大小和位置其执行流程是,会进行layout(),然后再执行一次performTraversals,但是此时mLayoutRequested=false,所以此次performTraversals并不会执行measure()、layout(),只会执行draw()。
因此,它有个优点是,可以避开父ViewGroup的布局约束,自由放置位置。但是也有个缺点是,因为缺少了measure(),所以如果draw()时需要用到measure()时产生的辅助数据,则会导致draw()效果异常。
所以可以用它来改变View的位置,但尽量不要用来改变View的大小。
tv.layout(100,100,200,200);
绘制异常:
只绘制出了一行,正常应该同上面一样绘制出两行,这是因为在measure()时会计算好绘制行数(查看源码可知是保存在一个Layout类型的成员变量中),这里直接使用旧的绘制行数,所以绘制异常。
3个TextView是放在一个LinearLayout中,改变中间这个TextView,并没有影响到下面的TextView
一些其他问题
前面讲了,在正常流程下,只有在setFrame()以后才能确认View的长宽和位置不过在《开发艺术探索》中,也讲了几种方法用于在不同时刻获取某个View的长宽和位置,但是除了ViewTreeObserver,个人感觉都很纠结。仅在此记录一下,遇到实际情况再实际选择使用
View.measure()
Activity.onWindowFocusChanged()
ViewTreeObserver
View.post()
后续更新
从Android 3.0/API 11开始,Android又给View增加了一些Property,如translation、rotation、scale等。通过修改他们也能够改变View的长宽及其在父ViewGroup中的位置
但是却没有改变left\top\right\bottom,也没有引发重新onDraw()
所以现在位置已经不能单纯用left\top\right\bottom来表示了,只能算是View布局完成以后的初始位置。
相关文章推荐
- Android控件设置——动态View的drawableLeft/ drawableRight/drawableTop/drawableBottom
- TextView 代码设置drawableLeft、drawableRight、drawableTop、drawableBottom
- View的位置--top, left, bottom, right
- 【Android】TextView动态设置android:drawableLeft|Right|Top|Bottom,SetColor
- Android-区分 View 的 translationX、Y , X、Y 和 Left、Top,Right、Bottom
- position:fixed; top: 0; right: 0; bottom: 0; left: 0;的意思
- 绝对能用-动态设置textview的drawableleft、drawableright、drawabletop、drawablebottom
- 面试总结(4):top、left、right、bottom 和 translationX、translationY 和 scrollX,scrollY的区别
- 在代码中设置TextView的drawableLeft、drawableRight、drawableTop、drawableBottom
- 元素position设置为fixed而未指定top、bottom、left、right时的定位
- 外边距margin-top right bottom left 设置方法 如果margin只设置两个值
- position:fixed; top: 0; right: 0; bottom: 0; left: 0;的意思
- Android在代码中设置控件的drawableLeft,drawableRight,drawableTop,drawableBottom。
- 动态设置android:drawableLeft|Right|Top|Bottom
- 安卓在代码中设置TextView的drawableLeft、drawableRight、drawableTop、drawableBottom
- Android在代码中设置控件的drawableLeft/Right/Top/Bottom
- glOrtho(left, right, bottom, top, near, far)
- 动态设置android:drawableLeft|Right|Top|Bottom
- position:fixed; top: 0; right: 0; bottom: 0; left: 0;的意思
- DrawableLeft,DrawableTop,Right,Bottom点击事件的实现