Sim*_*all 14 android view custom-component
我已经创建了一个自定义视图,onDraw()覆盖了画布上的位图.当我在布局文件中指定我想要它wrap_content时,它仍然会填满整个屏幕.onMeasure()这样说:
measure的基类实现默认为背景大小,除非允许更大的大小
MeasureSpec.子类应覆盖onMeasure(int,int)以提供更好的内容测量.
好酷,所以我知道我需要覆盖onMeasure()和使用MeasureSpec.根据这个答案
unex表示layout_width或layout_height值设置为wrap_content.你可以任意大小.
现在我遇到了我的问题,我如何onMeasure()测量我尚未创建的位图并测量/包装它?我知道其他Android视图必须做一些事情,因为如果设置为wrap_content,它们不会阻挡整个屏幕.提前致谢!
Sur*_*gch 24
1. Constructor // choose your desired size
2. onMeasure // parent will determine if your desired size is acceptable
3. onSizeChanged
4. onLayout
5. onDraw // draw your view content at the size specified by the parent
Run Code Online (Sandbox Code Playgroud)
如果您的视图可以是任何尺寸,它会选择多大的尺寸?这将是您的wrap_content尺寸,将取决于您的自定义视图的内容.例子:
dp,以px大小的设备.)如果您想要的大小使用繁重的计算,那么在构造函数中执行此操作.否则,您可以将其分配onMeasure.(onMeasure,onLayout并且onDraw可能会多次调用,这就是为什么在这里做繁重工作不好的原因.)
onMeasure是孩子告诉父母有多大的地方,父母决定这是否可以接受.这种方法经常被调用几次,每次都传递不同的大小要求,看看是否可以达到一些妥协.但最后,孩子需要尊重父母的身材要求.
当我需要复习如何设置我的时候,我总是回到这个答案onMeasure:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int desiredWidth = 100;
int desiredHeight = 100;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
//Measure Width
if (widthMode == MeasureSpec.EXACTLY) {
//Must be this size
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
width = Math.min(desiredWidth, widthSize);
} else {
//Be whatever you want
width = desiredWidth;
}
//Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
//Must be this size
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
height = Math.min(desiredHeight, heightSize);
} else {
//Be whatever you want
height = desiredHeight;
}
//MUST CALL THIS
setMeasuredDimension(width, height);
}
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,所需的宽度和高度仅设置为某些默认值.您可以事先计算它们并使用类成员变量在此处设置它们.
之后onMeasure,您的视图大小已知.这个大小可能是您要求的,也可能不是您所要求的,但这是您现在必须使用的.使用该大小在视图中绘制内容onDraw.
invalidate().这将导致onDraw再次调用(但不是所有其他先前的方法).requestLayout().这将重新开始测量和绘图的过程onMeasure.它通常与呼叫相结合invalidate().invalidate()在加载完所有内容后请求布局(不仅仅是).这看起来有点浪费,因为您要求整个视图层次结构连续布局两次.如果您无法在 onMeasure 调用之前测量位图,则可以返回大小为零,直到加载位图。加载后,使父 ViewGroup 无效以强制执行另一个测量(不记得 View 本身上的 invalidate() 是否会强制执行 onMeasure)。
| 归档时间: |
|
| 查看次数: |
11050 次 |
| 最近记录: |