10

次のようなビューをレイアウトしたいのですが、どうすればよいかわかりません。

  • 画面の下部には、固定サイズ (全幅と高さの dp 数) の通常のビューがあります。
  • 残りの垂直方向のスペースを埋めるために、glSurfaceView から継承するカスタム ビューを配置したいと思います。ただし、プログラムで設定される固定アスペクト比が必要であるという制限がありますが、アクティビティが作成される前に認識されます。(この場合、2:3 w:h であると仮定します)。

ここに私が想像しているものの小さな絵があります:

 .----------------------. 
 |   .--------------.   |  
 | b |              | b |  
 | g |              | g | 
 |   |              |   |  
 | i |  MySurface   | i | 
 | m |     View     | m | 
 | a |              | a | 
 | g |  (2:3 w:h)   | g | 
 | e |              | e | 
 |   *--------------*   | 
 |.--------------------.| 
 ||                    || 
 ||   SomeOtherView    || 
 ||                    || 
 |*--------------------*| 
 *----------------------* 

MySurfaceView の設定に関しては、通常の layout_width と layout_height は役に立たないと思います。なぜなら、画面が部分的にレイアウトされSomeOtherViewて配置されるまで、利用可能な画面サイズがわからないからです。

MySurfaceViewたとえば、使用可能な画面スペースを引数として渡し、ビューの幅と高さを設定する方法を決定できるようにするなど、オーバーライドしたい関数はありますか?

「インフレ」は私がここで探している正しい用語ですか? それは私が探しているものと関係があると思いますが、用語がよくわかりません。

私の研究の結果を以下に更新しました。正しい解決策の可能性があると思います。

4

4 に答える 4

13

さらに調査を行ったところ、何をする必要があるかがわかったと思います。

私がオーバーライドしようとしていた関数はonMeasure(int widthSpec, int heightSpec)、幅と高さの提案とともに親によって呼び出される です ( View.MeasureSpecを参照)。また、xmlMySurfaceViewに layout_width/height を設定しwrap_contentました。次に、onMeasureget が呼び出されると、使用可能なアスペクト比を計算し、ビューの幅と高さを必要に応じて設定できます。

この作業を行うために私が行った 2 番目のことMySurfaceViewは、FrameLayout の内部を唯一の子として配置することでした。私はもともと自分のイメージからMySurfaceViewRelativeLayout を持っていました。SomeOtherViewRelativeLayout の問題は、アスペクト比を修正できるように幅/高さを調整しないことです。

onMeasure測定中に複数回呼び出されます.RelativeLayoutの仕組みは、最初にカスタムビューに利用可能な高さを伝えずに幅を尋ね、その後戻ってきて高さを尋ねますが、幅は指定したものにロックされています.最初のパス ( MeasureSpec.EXACTLY)。これにより、使用可能な高さを知る前に幅を確認する必要があるため、特定の比率のビューを生成することができなくなります。

FrameLayout の内部に入ると、この問題は発生しませんでした。渡された MeasureSpecs にonMeasureは制限しかなかったからAT_MOSTです。これは、onMeasure を実行するたびに幅と高さを自由に変更できることを意味し、使用可能な領域を考慮して、必要に応じて縦横比を計算することができました。

これがすべてのケースで機能することはまだ確認されていませんが、うまくいけばこれが誰かを助けるでしょう.

于 2012-05-09T18:49:28.410 に答える
1

SurfaceView のサイズを設定するには、次を使用する必要があります。

    // Set surfaceview size in px
private void setVideoSize(int width, int height) {
    LayoutParams params = (LayoutParams) mYourSurfaceView.getLayoutParams();
    params.height = height;
    params.width = width;
    mYourSurfaceView.setLayoutParams(params);
}

画面のサイズを知りたい場合は、次のようにします。

Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
int width = display.getWidth(); 
int heigth = display.getHeight(); 

お役に立てれば

于 2012-05-09T06:25:11.587 に答える
0

これは私がテストした動作します。

public class Test_stflowActivity extends Activity {
    SurfaceView sv = null;
    RelativeLayout rl = null;
    int current_width = 0;
    int current_height   = 0;
    boolean already_created = false;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        sv = (SurfaceView) findViewById(R.id.SurfaceView1);
        rl = (RelativeLayout) findViewById(R.id.relativeLayout3);
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                current_height = rl.getHeight();
                while (current_height == 0) {
                    current_height = rl.getHeight();
                }
                current_width  = rl.getWidth();
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        update_surface(current_height, current_width);
                    }
                });
            }
        });
        thread.start();
        already_created = false;
    }

    void update_surface(int current_height,int current_width) {
        if (already_created == false){

            // CALCULATE ASPECTED RATIO ACCORDING TO ABOVE HEIGHT AND WIDTH.
            int calculated_height = current_height/2;
            int calculated_width = current_width /2;
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(calculated_height,
                                                                             calculated_width);
            lp.addRule(RelativeLayout.CENTER_IN_PARENT);
            sv.setLayoutParams(lp);
            sv.setVisibility(View.VISIBLE);
            already_created = true;
        }
        super.onResume();
    }
}

これが私が作成したレイアウトです。

<RelativeLayout
    android:id="@+id/relativeLayout2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="87dp"
        android:text="Button" />

</RelativeLayout>





<RelativeLayout
    android:id="@+id/relativeLayout3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_above="@+id/relativeLayout2"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true" >

    <android.view.SurfaceView
        android:id="@+id/SurfaceView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent" android:layout_centerInParent="true" android:background="#ff0000" android:visibility="invisible"/>

</RelativeLayout>

あなたが解決するのを手伝ってください。

于 2012-05-09T06:46:34.277 に答える