首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >重写onMeasure()的权威方式?

重写onMeasure()的权威方式?
EN

Stack Overflow用户
提问于 2011-09-15 05:16:14
回答 8查看 43.6K关注 0票数 89

重写onMeasure()的正确方法是什么?我见过不同的方法。例如,Professional Android Development使用MeasureSpec计算维度,然后以调用setMeasuredDimension()结束。例如:

代码语言:javascript
复制
@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()。例如:

代码语言:javascript
复制
@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()、布局、子视图的尺寸等的教程?

EN

回答 8

Stack Overflow用户

发布于 2012-04-27 02:52:56

其他的解决方案并不全面。它们在某些情况下可能会起作用,是一个很好的起点,但它们可能不一定能起作用。

当调用onMeasure时,您可能有也可能没有更改大小的权限。传递给您的onMeasure (widthMeasureSpecheightMeasureSpec)的值包含有关允许您的子视图执行哪些操作的信息。当前有三个值:

  1. MeasureSpec.UNSPECIFIED -你可以像你的like
  2. MeasureSpec.AT_MOST一样大-只要你想要的大小(直到规格大小),这是你的example.
  3. MeasureSpec.EXACTLY中的parentWidth -没有选择。父级已选择。

这样做的目的是为了让安卓可以多次通过,为每件商品找到合适的尺寸,更多细节见here

如果您不遵循这些规则,则不能保证您的方法有效。

例如,如果您想检查是否允许更改大小,可以执行以下操作:

代码语言:javascript
复制
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上可用,第二个版本在所有版本上都可用。

注意:您可能会发现resizeWidthresizeHeight总是false。如果我请求MATCH_PARENT,我发现情况就是这样。我可以通过在父布局上请求WRAP_CONTENT,然后在未指定的阶段请求大小为Integer.MAX_VALUE来修复此问题。这样做可以获得父对象在下一次通过onMeasure时允许的最大大小。

票数 69
EN

Stack Overflow用户

发布于 2011-10-21 02:45:32

文档是这方面的权威:http://developer.android.com/guide/topics/ui/how-android-draws.htmlhttp://developer.android.com/guide/topics/ui/custom-components.html

总而言之:在被覆盖的onMeasure方法的末尾,应该调用setMeasuredDimension

您不应该在调用setMeasuredDimension之后调用super.onMeasure,这只会擦除您设置的所有内容。在某些情况下,您可能希望先调用super.onMeasure,然后通过调用setMeasuredDimension来修改结果。

不要在onMeasure中调用setLayoutParams。布局在测量后的第二次遍历中发生。

票数 39
EN

Stack Overflow用户

发布于 2016-03-13 11:31:35

我认为这取决于您要重写的父级。

例如,如果您正在扩展一个ViewGroup (如FrameLayout),当您测量好大小后,您应该像下面这样调用

代码语言:javascript
复制
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);就足够了。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7423082

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档