【问题标题】:getWidth() returns 0 if set by android:layout_width="match_parent"如果由 android:layout_width="match_parent" 设置,getWidth() 返回 0
【发布时间】:2013-01-29 21:48:24
【问题描述】:

我有一个扩展 ImageView 的名为 FractalView 的类。我的目标是使用具有整个屏幕大小的此类绘制分形。它是我的活动布局文件中唯一的视图,除了顶级 LinearLayout:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
    android:background="#FFFFFFFF">

    <com.antonc.fractal_wallpaper.FractalView
        android:id="@+id/fractal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"/>
</LinearLayout>

如您所见,我对 FractalView 和 LinearLayout 的 layout_width 和 layout_height 都使用了“match_parent”。在这一点上,我假设 FractalView 的大小设置为某个值,因为它匹配它的父级,它匹配它的父级(即整个屏幕)。 然后我尝试使用 getWidth() 和 getHeight() 检测 FractalView 可用的大小:

public class FractalView extends ImageView {

private Context mContext;
private Handler mHandler;

private int mScrWidth;
private int mScrHeight;

public FractalView(Context context) {
    super(context);
    mContext = context;
    init();
}

private void init() {

    mScrWidth = getWidth();
    mScrHeight = getHeight();
    // Breakpoint
}

@Override
protected void onDraw(Canvas canvas) {
    [...]
}

}

但是当我的代码到达断点时,调试器显示 mScrWidth 和 mScrHeight 为零。我尝试使用 getMeasuredWidth() 和 getMaxWidth(),但它们也返回不正确的值。我已经阅读了几个类似问题的答案,即this one,他们都解释说 getWidth() 返回图像的大小,而我真正需要的是图像的宽度此视图可用的区域,之前我开始绘制。

有没有办法检索这些宽度和高度值?

【问题讨论】:

  • 既然愿意用全屏,可以看一下获取设备的宽高(这个不建议)。如果 getMeasuredWidth() 返回错误的值,您应该等到它被测量并再次调用该函数。例如在另一个 Activity 生命周期方法中调用该函数(例如 onResume 而不是 onCreate),希望这会有所帮助
  • 由于您使用的是 ImageView,您可以做的另一件事是覆盖 setImageBitmap()。
  • 我找到了一种方法来做到这一点,并将其作为答案发布。我现在不会接受我自己的答案,因为也许有人知道更好的方法来做到这一点。 Simon, user1281750 - 谢谢,我会看看你建议的方法。

标签: android android-layout


【解决方案1】:

onMeasure() 之后,视图的大小才可用,尤其是当它设置为wrap_contentfill_parent 时。

您应该在 View 代码中或在 Layout Tree Observer 中访问 onMeasure() 或之后的大小:

LinearLayout layout = (LinearLayout)findViewById(R.id.mylayout);
ViewTreeObserver vto = layout.getViewTreeObserver(); 
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
    @Override 
    public void onGlobalLayout() { 
        this.layout.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
        int width  = layout.getMeasuredWidth();
        int height = layout.getMeasuredHeight(); 

    } 
});

您还需要将 android:id="@+id/mylayout" 添加到您的 LinearLayout 以使第二个工作。

【讨论】:

  • 我最终覆盖了 onMeasure() 并在调用 super.onMeasure(widthMeasureSpec, heightMeasureSpec) 之后立即调用 getMeasuredWidth()getMeasuredHeight()。这似乎可以解决问题。
【解决方案2】:

我在输入问题时想出了一个方法。 我没有尝试在构造函数方法中检索大小,而是将代码移至 onDraw() 方法,如下所示:

private void init() {

}

@Override
protected void onDraw(Canvas canvas) {
    mScrWidth = canvas.getWidth();
    mScrHeight = canvas.getHeight();
    [...]
}

这会返回正确的尺寸。

【讨论】:

  • 查看 Raghav 的回答(以及我的 cmets)。 onDraw 中不需要的任何代码都是错误代码,因为每次绘制视图时都会执行它。如果您不经常更新视图,这可能无关紧要,但这不应该成为在错误的地方做事的借口。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-30
  • 1970-01-01
相关资源
最近更新 更多