Android 自定义View (四)
来源:互联网 发布:mac怎么下载office 编辑:程序博客网 时间:2024/05/16 07:53
Create Drawing Objects
The most important step in drawing a custom view is to override the onDraw()
method.
The android.graphics
framework divides drawing into two areas:
- What to draw, handled by
Canvas
- How to draw, handled by
Paint
.
Handle Layout Events
If your view doesn't need special control over its size, you only need to override one method: onSizeChanged()
.
If you need finer control over your view's layout parameters, implement onMeasure()
.
View在屏幕上显示出来要先经过measure(计算)和layout(布局).
什么时候调用onMeasure方法?
onMesure函数是用来测量View本身的大小,原型如下:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
}
两个参数widthMeasureSpec, heightMeasureSpec由父ViewGroup传入, 指明控件可获得的空间以及关于这个空间描述的元数据.
这两个参数,由ViewGroup中的layout_width,layout_height和padding以及View自身的layout_margin共同决定。权值weight也是尤其需要考虑的因素,有它的存在情况可能会稍微复杂点。
了解了这两个参数的来源,还要知道这两个值的作用。我们只取heightMeasureSpec作说明。这个值由高32位和低16位组成,高32位保存的值叫specMode,可以通过如代码中所示的MeasureSpec.getMode()获取;低16位为specSize,同样可以由MeasureSpec.getSize()获取。那么specMode和specSize的作用有是什么呢?要想知道这一点,我们需要知道代码中的最后一行,所有的View的onMeasure()的最后一行都会调用setMeasureDimension()函数的作用——这个函数调用中传进去的值是View最终的视图大小。也就是说onMeasure()中之前所作的所有工作都是为了最后这一句话服务的。
我们知道在ViewGroup中,给View分配的空间大小并不是确定的,有可能随着具体的变化而变化,而这个变化的条件就是传到specMode中决定的,specMode一共有三种可能:
MeasureSpec.EXACTLY:父视图希望子视图的大小应该是specSize中指定的。
MeasureSpec.AT_MOST:子视图的大小最多是specSize中指定的值,也就是说不建议子视图的大小超过specSize中给定的值。
MeasureSpec.UNSPECIFIED:我们可以随意指定视图的大小。
这些模式和我们平时设置的layout参数fill_parent, wrap_content有什么关系呢?
经过代码测试就知道,当我们设置width或height为matc_parent时,容器在布局时调用子 view的measure方法传入的模式是EXACTLY,因为子view会占据剩余容器的空间,所以它大小是确定的。
而当设置为 wrap_content时,容器传进去的是AT_MOST, 表示子view的大小最多是多少,这样子view会根据这个上限来设置自己的尺寸。当子view的大小设置为精确值时,容器传入的是EXACTLY, 而MeasureSpec的UNSPECIFIED模式目前还没有发现在什么情况下使用。
一般写法如下(Android APIDemos LableView):
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } /** * Determines the width of this view * @param measureSpec A measureSpec packed into an int * @return The width of the view, honoring constraints from measureSpec */ private int measureWidth(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else { // Measure the text result = (int) mTextPaint.measureText(mText) + getPaddingLeft() + getPaddingRight(); if (specMode == MeasureSpec.AT_MOST) { // Respect AT_MOST value if that was what is called for by measureSpec result = Math.min(result, specSize); } } return result; } /** * Determines the height of this view * @param measureSpec A measureSpec packed into an int * @return The height of the view, honoring constraints from measureSpec */ private int measureHeight(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); mAscent = (int) mTextPaint.ascent(); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else { // Measure the text (beware: ascent is a negative number) result = (int) (-mAscent + mTextPaint.descent()) + getPaddingTop() + getPaddingBottom(); if (specMode == MeasureSpec.AT_MOST) { // Respect AT_MOST value if that was what is called for by measureSpec result = Math.min(result, specSize); } } return result; }
- Android 自定义View (四)
- Android 自定义View (四)
- Android自定义View (四) CustomVolumControlBar
- Android自定义View教程(四)
- Android view 详解(四) 自定义view
- Android自定义控件之自定义View(四)
- android自定义控件(四) View中的方法
- 初学Android,开发自定义的View(四)
- android自定义控件(四) View中的方法
- Android 自定义View (四) 视频音量调控
- Android 自定义View (四) 视频音量调控
- Android 自定义View (四) 视频音量调控
- Android 自定义View (四) 视频音量调控
- Android 自定义View (四) 视频音量调控
- android自定义控件(四) View中的方法
- Android 自定义View (四) 视频音量调控
- Android 自定义View (四) 视频音量调控
- android自定义控件(四) View中的方法
- 品牌营销新闻宣传网络执行哪家强?
- windowsphone中WebBrowser中的页面按级回退功能
- 即时通讯 视频会议开源技术选择
- windowsphone中WebBrowser中的页面按级回退功能
- 《深入C++面向对象模型》之拷贝构造函数
- Android 自定义View (四)
- iOS 之NSDictionary深复制
- ContentProvider案例
- 云
- 使用VS2008编译OpenCV2.2.0源码
- 多线程内存模型及同步和互斥简介
- WP7 如何禁用WebBrowser 控件缩放和左右移动
- platform平台总结
- iOS 之属性方法的选取原则