12

たとえば、ウィジェットのサイズを相対寸法で指定するレイアウトがあります。

<LinearLayout ... layout_height="fill_parent">
     <ImageView ... layout_height="wrap_content" />
     <TextView ... layout_height="120dp" />
</LinearLayout>

直後にonCreate、ImageView の高さがどのくらいか知りたいです。どうやってするか?

注:を呼び出すgetHeight()onCreate、0 が返されます。

私も試してみimageView.postDelayedましたが、2.1 エミュレーターでは動作しますが、1.5 エミュレーターでは失敗します (私も 0 を取得しました)。

最後に、 を作成しようとしましたが、 10 ミリ秒の遅延でHandler呼び出しました。handler.postDelayed2.1 と 1.5 の両方のエミュレーターで動作しますが、Eclipse デバッガーでプログラムを起動すると失敗しました (したがって、遅延を使用しても、イメージビューがレイアウトされた後に高さが取得されるとは限りません)。

4

2 に答える 2

12

サイズが 0 になる理由は、アクティビティが完全に作成されるまで、つまり onCreate()、onStart()、および onResume() がすべて完了するまでレイアウトが終了しないためです。私が知っている正確なサイズを取得する最も簡単な方法は、ボタンでクリック リスナーを使用するなどして、レイアウトが終了した後にメソッドを呼び出すことです。ボタンはレイアウトが完了するまで表示されないため、クリック リスナーが起動されるまでにサイズが使用可能になっている必要があります。

これは推測にすぎませんが、システムが画面のレイアウトを終えたばかりのときにレイアウト サイズをいじりたくないため、これを正確に行うのは難しいと思います。彼らが「onLayoutFinished()」コールバックを提供した場合、その中でレイアウトを変更すると、ループに陥る可能性があります。たとえば、次のように想像してください。レイアウトが完了しました。onLayoutFinished() が呼び出され、そこでレイアウトを変更します。既存のレイアウトは無効になりました。レイアウトのやり直し。onLayoutFinished() が再度呼び出されました。あなたのコードは再び呼び出されます - など。

それを行う別の方法は、カスタム ビューを作成してonMeasure(int, int)メソッドをオーバーライドすることです。システムはそのメソッドをトリガーして、各ビューのサイズを取得します。以下の例のようなものを使用すると、レイアウトが完了する前に推奨サイズを取得できます。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    //getMeasuredHeight() and getMeasuredWidth() now contain the suggested size
}

(レイアウトの都合上、この後サイズが変わる可能性もあると思うので、目安サイズと書きましたが、少し前に読んだものの漠然とした記憶で、詳しく実験したことはありません。)を使用して、使用するサイズを変更することもできますsetMeasuredDimension(newX, newY)

于 2010-05-19T10:04:41.597 に答える
7

View オブジェクトは onSizeChanged(int w, int h, int oldw, int oldh) というメソッドを提供します。レイアウトがそのコンポーネントの 1 つのサイズを変更するときに呼び出されます。このメソッドをオーバーライドすると、このメソッドのバージョンのコードは、次のスニペットに示すように、それ自体のサイズを認識します。

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    bounds = new Rect();
    this.getDrawingRect(bounds);
    // bounds will now contain none zero values
}
于 2011-01-01T18:28:19.093 に答える