0

我有一些这样的代码:

 final int height = 0; //I want to get this height after Predraw view
 view.addOnPreDrawListener(new OnPreDrawListener()
    {

        @Override
        public boolean onPreDraw()
        {
            int myHeight = itemLayout.getMeasuredHeight();
            height = myHeight; //this line has error
            return false;
        }
    });

问题是我如何从侦听器那里获得价值(尤其是原始类型)。它总是显示

 Cannot refer to a non-final variable height inside an inner class defined in a different method 

然后我尝试将变量更改为final,它显示错误:

 The final local variable height cannot be assigned, since it is defined in an enclosing type

我不知道为什么 API 很难使用。

4

6 回答 6

3

之前将其声明为全局 int myHeight;onCreate(....)

于 2012-05-15T09:12:24.947 回答
2

您不能在高度初始化时使用“final”,然后再尝试更改它。但是,您可以将变量分配给类而不是函数内。

private int tmpHeight = 0;

这将允许您从侦听器中访问变量。

于 2012-05-15T09:14:18.190 回答
2

你提到的两个错误都是正确的

1) 内部类内部不能访问非final变量

2) final 变量在初始化后不能改变

将高度声明为类内的全局变量而不是任何方法将解决您的问题

 int myHeight; 
于 2012-05-15T09:15:03.400 回答
2

处理这个问题的最简单方法是让你的Activityimplement OnPreDrawListener.

public class MyActivity extends Activity implements OnPreDrawListener{
  int height;

  method(){
    ..
    view.addOnPreDrawListener(this);
    ..
  }

  @Override
  public boolean onPreDraw(){
    height = itemLayout.getMeasuredHeight();
  }  
}

问题不在于 API 的“复杂性”。这是一个真正的 Java 问题,涉及所涉及的各种变量的生命周期。通过不声明变量heightfinal,当您的内部匿名类尝试访问它时,它可能会从堆栈中清除。由于必须标记它final,你被迫保证它的寿命height

通过执行我的建议,您将 Activity 对象和侦听器对象的生命等同起来。

于 2012-05-15T09:24:43.067 回答
1

使其成为类级别变量也是一种选择。

于 2012-05-15T09:12:38.887 回答
1

错误不在侦听器中,而是在height作为最终变量的声明中。

这意味着它在初始化后无法更改,您必须从中删除final:

int height = 0; 
view.addOnPreDrawListener(new OnPreDrawListener() {

    @Override
    public boolean onPreDraw() {
        int myHeight = itemLayout.getMeasuredHeight();
        height = myHeight; 
        return false;
    }
});
于 2012-05-15T09:12:39.317 回答