Java中如何访问匿名内部类方法内定义的局部变量?
问题根因
- 作用域限制:
thumbnailHeight、thumbnailWidth是OnGlobalLayoutListener匿名内部类中onGlobalLayout方法的局部变量,作用域仅局限于该方法内部,方法外无法直接访问,修改为static、final也无法突破局部变量的作用域限制。 - 执行时序问题:
addOnGlobalLayoutListener属于异步监听注册逻辑,onGlobalLayout回调需要等mPhotoView完成系统测量、布局流程后才会触发。你写在监听外的updatePhotoView执行时,回调还未运行,就算把变量提升到外部,此时也只能拿到默认初始值,无法获取到正确的View宽高。
解决方案
方案1:直接在回调内调用目标方法(最推荐)
将updatePhotoView的调用逻辑移到onGlobalLayout回调内部,同时记得执行完后移除监听,避免后续布局变动重复触发回调:
mPhotoView = (ImageView)v.findViewById(R.id.crime_photo); mPhotoView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int thumbnailHeight = mPhotoView.getHeight(); int thumbnailWidth = mPhotoView.getWidth(); // 回调内直接调用方法 updatePhotoView(thumbnailHeight, thumbnailWidth); // 移除当前监听,避免重复触发 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { mPhotoView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { // 兼容低版本API mPhotoView.getViewTreeObserver().removeGlobalOnLayoutListener(this); } } });
方案2:将宽高声明为外部类成员变量
如果后续需要在其他场景使用这两个宽高值,可以将其提升为CrimeFragment的成员变量:
public class CrimeFragment extends Fragment { // 声明为Fragment成员变量 private int mThumbnailHeight; private int mThumbnailWidth; private ImageView mPhotoView; // 原有其他代码... private void initView(View v) { mPhotoView = (ImageView)v.findViewById(R.id.crime_photo); mPhotoView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 给成员变量赋值 mThumbnailHeight = mPhotoView.getHeight(); mThumbnailWidth = mPhotoView.getWidth(); updatePhotoView(mThumbnailHeight, mThumbnailWidth); // 移除监听 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { mPhotoView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { mPhotoView.getViewTreeObserver().removeGlobalOnLayoutListener(this); } } }); } }
注意:成员变量在
onGlobalLayout触发前为默认值0,不要在回调执行前调用需要依赖这两个值的逻辑。
内容的提问来源于stack exchange,提问作者Aravind Varma
相关产品推荐
相关产品推荐

