1

使用可能なスペースを埋めるために線形レイアウトで画像をスケーリングしようとしていますが、レイアウトの幅に対して取得している値がわかりません。main.xml レイアウト ファイルの関連部分は次のとおりです。

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LeftButtonsLayout"
    android:layout_width="0dip"
    android:layout_height="fill_parent"
    android:layout_weight="10"
    android:orientation="vertical" >

    <TextView
    android:id="@+id/Jump"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/jump"
    android:textStyle="bold"
    android:padding="5dip"
    />
    <ImageView
    android:id="@+id/JumpButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:src="@drawable/jump"
    android:contentDescription="@string/jump"
    android:padding="5dip"
    />
<LinearLayout

デバッグ出力がある私のアクティビティの onCreate() メソッドは次のとおりです。

public void onCreate (Bundle savedInstanceState) {

    setContentView(R.layout.main);

    LinearLayout leftButtonsLayout = (LinearLayout) findViewById(R.id.LeftButtonsLayout);
    imageView = (ImageView) findViewById(R.id.ResetButton);

    Log.d("DEBUG", CLASS_NAME + "scaleLeftButtonsLayoutContents: \n" + 
          "linear layout height: " + leftButtonsLayout.getHeight() + "\n" +
      "text height: " + ((TextView)findViewById(R.id.Jump)).getHeight()  + "\n" +
          "image height: " + imageView.getLayoutParams().height); 

}

1) Log.d() デバッグ出力の後に setContentVew() 呼び出しを配置すると、Null Pointer Exception が発生します。なんで?ビューで使用される前に LinearLayout にメモリが割り当てられていませんか?

2) 私が見るプリントは次のとおりです: 線形レイアウトの高さ: 0 テキストの高さ: 0 画像の高さ: -2 ここで何が間違っていますか? デバイスの画面に imageView が表示されているので、ここで適切な値が表示されることを期待していました。

3) imageView.getLayoutParams().height = newHeight を使用して画像をスケーリングすることを計画していました。そうする権利はありますか?これを行うと、画面上の imageView が自動的に更新されますか、それとも setContentView() を再度実行する必要がありますか?

よろしくお願いします。

アップデート

皆様、ご回答ありがとうございます。アクティビティの onWindowFocusChanged() メソッドをオーバーライドしましたが、以下のネストされた ImageView のサイズを確認すると、-2 と報告されます。サイズ変更は機能しますが、正常な値であるはずなのになぜ -2 なのか不思議です。私のコードは次のとおりです。

@Override
public void onWindowFocusChanged (boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);

    if (hasFocus)
        scaleLeftButtonsLayoutContents();
}


private void scaleLeftButtonsLayoutContents () {
    LinearLayout leftButtonsLayout = (LinearLayout)findViewById(R.id.LeftButtonsLayout);

    imageView = (ImageView) findViewById(R.id.JumpButton);      
    Log.d("TAG", CLASS_NAME + "JumpButton.height " + imageView.getLayoutParams().height);
    imageView.getLayoutParams().height = verticalSpaceAvailable;
    imageView.getLayoutParams().width = verticalSpaceAvailable;

    leftButtonsLayout.requestLayout();
}

これにより次の出力が生成されます: JumpButton.height -2

サイズを変更すると正常な画像が生成されますが、最初の高さが -2 なのはなぜですか?

4

3 に答える 3

3

あなたのポイントに答えるために、

1) Button または ImageView を初期化していないためです。これを行う前に Log を呼び出すため、明らかに Button と ImageView は null であるため、例外が発生します。

2)初期化は、幅と高さを提供するためにビューが完全に描画されることを意味するものではありません。そのため、描画されるまでの時間を提供する必要があります。残念ながら、描画にかかる正確な時間はわかりません。Androidはこのメソッドを提供し、

  @Override 
public void onWindowFocusChanged(boolean hasFocus) 
{ 
   // which gets called when your view is drawn. 
 }  

ちょうど今、ここで同様の質問に答えました。

したがって、アクティビティのこのメソッド内にログを追加し、結果の幅と高さを確認する必要があります。

3) 3 番目の質問に答えるには、setContentView() をもう一度呼び出すべきではありません。これにより、他の例外がスローされる可能性があります。ただし、スケーリングを検討する場合、これを行うためにいくつかのビットマップを利用することがあります。

于 2012-06-18T08:07:18.860 に答える
3

ここにあなたのためのいくつかの答えがあります:

1) view.getHeight() を呼び出した後に setContentView を配置すると、そのビューはアクティビティ コンテンツに設定されていないため、null ポインターが取得されます。したがって、アクティビティのコンテンツに設定する前に参照を取得することはできません。

2) ビューにレイアウトする時間がないため、それがわかります.. ビューの高さ/幅を確認したい場合は、次のように ViewTreeObserver リスナーを使用することをお勧めします。

view.getViewTreeObserver().addOnGlobalLayoutListener(new     ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                /* don't forget to remove the listener after you use it once */
                view.getViewTreeObserver().removeGlobalOnLayoutListener(this);

                Log.d("MY VIEW WIDTH","width:"+view.getWidth());

            }
        });

view.requestLayout()3) ビューのレイアウト パラメータを設定したら、ビューが更新されることを確認するために呼び出すことを忘れないでください。setContentView() を再度呼び出す必要はありません。

編集: また、LinearLayout の幅は、fill_parent でない場合は少なくとも wrap_content である必要があり、リニア レイアウトの子ビューを表示する場合は 0 より大きい値である必要があります。

于 2012-06-18T08:15:18.030 に答える
1

このようにすることはできません。linearlayout はアクティビティのメイン コンテナだからです。メイン レイアウトにandroid:layout_weight="10"andを指定することはできません。android:layout_width="0dip"この外側に Linear レイアウトを 1 つ作成しandroid:id="@+id/LeftButtonsLayout"、レイアウトの高さと幅をfill_parentまたはに指定しmatch_parentます。これはあなたの場合に機能します。

もう 1 つ、 の前にレイアウトの要素を呼び出すことはできませんsetContentView

于 2012-06-18T08:12:49.920 に答える