重写onMeasure()的正确方法是什么?我见过不同的方法。例如,Professional Android Development使用MeasureSpec计算维度,然后以调用setMeasuredDimension()结束。例如:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth/2, parentHeight);
}
另一方面,根据this post的说法,“正确”的方法是使用MeasureSpec,先调用setMeasuredDimensions()、,然后调用setLayoutParams(),最后调用super.onMeasure()。例如:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth/2, parentHeight);
this.setLayoutParams(new *ParentLayoutType*.LayoutParams(parentWidth/2,parentHeight));
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
那么哪种方式才是正确的呢?这两种方法对我来说都不是100%有效。
我想我真正想问的是,有没有人知道关于onMeasure()、布局、子视图的尺寸等的教程?
发布于 2012-04-27 02:52:56
其他的解决方案并不全面。它们在某些情况下可能会起作用,是一个很好的起点,但它们可能不一定能起作用。
当调用onMeasure时,您可能有也可能没有更改大小的权限。传递给您的onMeasure (widthMeasureSpec
,heightMeasureSpec
)的值包含有关允许您的子视图执行哪些操作的信息。当前有三个值:
MeasureSpec.UNSPECIFIED
-你可以像你的likeMeasureSpec.AT_MOST
一样大-只要你想要的大小(直到规格大小),这是你的example.MeasureSpec.EXACTLY
中的parentWidth
-没有选择。父级已选择。这样做的目的是为了让安卓可以多次通过,为每件商品找到合适的尺寸,更多细节见here。
如果您不遵循这些规则,则不能保证您的方法有效。
例如,如果您想检查是否允许更改大小,可以执行以下操作:
final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
boolean resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
boolean resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;
使用此信息,您将知道是否可以像在代码中那样修改这些值。或者如果你被要求做一些不同的事情。解决所需大小的一种快速简单的方法是使用以下方法之一:
int resolveSizeAndState (int size, int measureSpec, int childMeasuredState)
int resolveSize (int size, int measureSpec)
第一个版本只在Honeycomb上可用,第二个版本在所有版本上都可用。
注意:您可能会发现resizeWidth
或resizeHeight
总是false。如果我请求MATCH_PARENT
,我发现情况就是这样。我可以通过在父布局上请求WRAP_CONTENT
,然后在未指定的阶段请求大小为Integer.MAX_VALUE
来修复此问题。这样做可以获得父对象在下一次通过onMeasure时允许的最大大小。
发布于 2011-10-21 02:45:32
文档是这方面的权威:http://developer.android.com/guide/topics/ui/how-android-draws.html和http://developer.android.com/guide/topics/ui/custom-components.html
总而言之:在被覆盖的onMeasure
方法的末尾,应该调用setMeasuredDimension
。
您不应该在调用setMeasuredDimension
之后调用super.onMeasure
,这只会擦除您设置的所有内容。在某些情况下,您可能希望先调用super.onMeasure
,然后通过调用setMeasuredDimension
来修改结果。
不要在onMeasure
中调用setLayoutParams
。布局在测量后的第二次遍历中发生。
发布于 2016-03-13 11:31:35
我认为这取决于您要重写的父级。
例如,如果您正在扩展一个ViewGroup (如FrameLayout),当您测量好大小后,您应该像下面这样调用
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
因为你可能想用ViewGroup来做rest工作(对子视图做一些事情)
如果你正在扩展一个视图(比如ImageView),你可以直接调用this.setMeasuredDimension(width, height);
,因为父类会像你通常做的那样做一些事情。
总而言之,如果你想要你的父类免费提供的一些特性,你应该调用super.onMeasure()
(通常传递MeasureSpec.EXACTLY模式度量规范),否则调用this.setMeasuredDimension(width, height);
就足够了。
https://stackoverflow.com/questions/7423082
复制相似问题