用于覆盖onMeasure()的专有方法?

U A*_*los 87 android android-layout

覆盖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);
}
Run Code Online (Sandbox Code Playgroud)

另一方面,根据这篇文章,"正确"的方法是使用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);
}
Run Code Online (Sandbox Code Playgroud)

那么哪种方式正确?这两种方法都没有对我有效.

我想我真正想要的是有没有人知道一个解释onMeasure(),布局,子视图尺寸等的教程?

Gri*_*ace 67

其他解决方案并不全面.它们可能在某些情况下起作用,并且是一个很好的起点,但它们可能无法保证工作.

当onMeasure被调用时,您可能有权也可能无权更改大小.传递给onMeasure(widthMeasureSpec,heightMeasureSpec)的值包含有关您的子视图允许执行的操作的信息.目前有三个值:

  1. MeasureSpec.UNSPECIFIED - 你可以像你想的那样大
  2. MeasureSpec.AT_MOST- 尽可能大(最大规格尺寸),这是parentWidth你的例子.
  3. MeasureSpec.EXACTLY- 没有选择.家长选择了.

这样做是为了让Android可以进行多次传递以找到每个项目的正确大小,有关详细信息,请参阅此处.

如果您不遵守这些规则,则无法保证您的方法有效.

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

final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
boolean resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
boolean resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;
Run Code Online (Sandbox Code Playgroud)

使用此信息,您将知道是否可以像在代码中一样修改值.或者,如果您需要做一些不同的事情.解决所需大小的快速简便方法是使用以下方法之一:

int resolveSizeAndState(int size,int measureSpec,int childMeasuredState)

int resolveSize(int size,int measureSpec)

虽然第一个仅适用于Honeycomb,但第二个适用于所有版本.

注意:您可能会发现resizeWidthresizeHeight总是错误的.如果我要求,我发现情况就是这样MATCH_PARENT.我能够通过请求WRAP_CONTENT我的父布局,然后在非常阶段请求大小来解决这个问题Integer.MAX_VALUE.这样做可以为您提供父母在下次浏览onMeasure时允许的最大大小.


sat*_*ine 39

该文档是此事的权威:http://developer.android.com/guide/topics/ui/how-android-draws.htmlhttp://developer.android.com/guide/topics/ui/custom -components.html

总结一下:在重写onMeasure方法结束时,您应该调用setMeasuredDimension.

你不应该在打电话super.onMeasure后打电话setMeasuredDimension,这只会擦除你设置的内容.在某些情况下,您可能需要先调用第super.onMeasure一个,然后通过调用来修改结果setMeasuredDimension.

不要叫setLayoutParamsonMeasure.布局在测量后的第二遍中发生.