4

私はこれに対する解決策を見つけようとしていますが、おそらく「onMeasure()」メソッドが Android でうまく機能する方法を理解していません!

Android でカスタム ビューを「動的」にしたのはこれが初めてなので、画面の大きさに応じてビューのサイズを変更するには、「onMeasure()」メソッドをオーバーライドする必要があることを学びました。ビューを画面の幅の半分に加えて少し余分にしたいので (この数値は、3 から 5 の間の比較的小さい限り、任意です)、onMeasure メソッド用に次のコードを書きました。

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    int halfWidth = (MeasureSpec.getSize(widthMeasureSpec) / 2) - 5;

    this.setMeasuredDimension((int) halfWidth, (int) halfWidth);
}

私がオンラインで見つけたどこにでも、似たようなことを達成しようとしているときよりもはるかに多くのコードがあるため、これはひどいやり方だと確信しています!

これらのビューを XML で隣り合わせに配置すると、最初のビューのサイズは正しくなります (実際には、幅の半分のサイズから少しだけマイナスしたサイズになります)。最後のビュー マイナスもう少し! (私はそれの写真を投稿しますが、残念ながらそうするのに十分な評判がありません...)

XML のどこに配置しても、2 つのボックスは同じサイズでなければなりませんそれらはすべて、画面の幅の半分のサイズから少し余分なものを引いたものにする必要があります。

「setMeasuredDimension()」の使用方法に関係があることは知っていますが、それが何であるかはわかりません。誰かが私のために物事を少し明確にしてくれることを本当に願っています! ありがとう!:)

4

4 に答える 4

3

ティムが言ったことに基づいて、今日、少し実験してこれを実際に達成しました。「onMeasure()」から離れて、次のコードだけを書きました。

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    // Call the super class.
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    // Set the dimensions of this view.
    this.setMeasuredDimension((int) width, (int) width);
}

幅はグローバル フロートです。幅はどこから?サイズを変更するビューに記述したこのメソッドから幅を派生させました。

public void initSize(float size)
{
    width = size;
    this.invalidate();
}

ビューを再描画するために「invalidate()」を呼び出します。ただし、何かがこのメソッドを呼び出す必要があるため、アクティビティで呼び出します。まず、次のコードを使用して、ビューではなくアクティビティで画面のサイズを取得します。

Display thisDisplay = this.getWindowManager().getDefaultDisplay();
Point desiredSize = new Point();
display.getSize(desiredSize);
int width = size.x;

以前は、「thisDisplay」で「getWidth()」というメソッドを呼び出すことができましたが、このメソッドは廃止されたため、代わりに「getSize()」を使用する必要があります。最後に、コンストラクターを初期化した直後に、「initSize()」メソッドを呼び出します。

nameBox = (InfoBoxView) findViewById(R.id.nameBox);
    nameBox.initSize(width);

これで、すべてのビューが同じサイズになります。これがこれを行うための最良の方法かどうかはわかりませんが、今のところうまくいきます。誰もが知っているようにここに投稿すると思いました. :)

于 2012-05-20T13:41:47.650 に答える
0

onMeasureのドキュメントを読んで、それがどのように機能するかを確認する必要があると思います。

ビューが含まれるレイアウトコンテナのタイプに応じて、実際には複数回呼び出されます。正確な詳細は、ViewGroupごとに異なります。一般に、寸法は最初は最も緩く、その後、より多くのコンポーネントが配置されるにつれて、より細かくなります。

onMeasureが呼び出されたとき、最初にを呼び出して、受け取ったMeasureSpecの種類を確認する必要がありますMeasureSpec.getMode(widthMeasureSpec)MeasureSpec.AT_MOSTこれはまたはのいずれかを返しますMeasureSpec.EXACTLY

AT_MOSTが返される場合は、現時点でビューが埋めることができる最大の領域を示しています。最初のビューをレイアウトする場合、他のコンポーネントはまだレイアウトされていないため、最初のビューは最大で画面の幅全体を使用できると言っている可能性があります。コンテナの幅全体を2で割った後、を呼び出して、水平レイアウトの50%を使用して満足していることをコンテナに伝えますsetMeasuredDimension

次に、onMeasureが2番目のビューに対して呼び出されると、最初のビューに対して画面の半分を既に要求しているため、コンテナの水平方向の幅の半分しか使用できなくなります。

次に、その数を2で割って、2番目のビューのコンテナの水平方向の幅の25%だけを残し、最初のビューの水平方向の幅の50%にします。

onMeasureをオーバーライドすることは、ビューが画面の半分を使用するための適切な方法ではないことをお勧めしますが、それがどのように機能するかを説明したいと思います。標準のxmlレイアウトだけではこれを達成できないと思う理由はありますか?

編集:質問をもう一度読み直してください。あなたの問題は、widthMeasureSpecが画面の幅と同じことを意味すると想定していることだと思います(そうではありません)。画面の幅を適切に照会し、setMeasureDimensionそれに基づいて呼び出すことができますが、すべての場合に機能するとは限りません。注意しない場合は、Measureに基づいて割り当てられた幅よりも広い幅を要求できます。onMeasureまたは、 withと呼ばれることもあります。MeasureSpec.EXACTLYその時点で、指定された幅または高さを使用する以外に選択肢はありません。

于 2012-05-20T00:34:16.980 に答える
0

問題は、あなたの主張によると、親ビューのサイズもおそらく半分のサイズに縮小されていることだと思います。したがって、私はコードを提案します:

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
   // Prevent reducing the size of the parent view
   super.onMeasure(widthMeasureSpec, heightMeasureSpec);

   int halfWidth = (MeasureSpec.getSize(widthMeasureSpec) / 2) - 5;

   this.setMeasuredDimension((int) halfWidth, (int) halfWidth);
}

また、あなたの XML レイアウトはどのようなものですか? それが問題であることを疑っていますが、それも修正する必要があるかもしれません。

私は自分の Android SDK でこれを試しませんでした。

于 2012-05-20T05:14:58.197 に答える