6

Android 用の拡張現実アプリケーションを構築しようとしていますが、サーフェス ビューのレイヤー化の問題に遭遇しました。グラフィックをオーバーレイするカメラ プレビューを表示するためのサーフェス ビューと、グラフィックを描画するためのサーフェス ビューが必要です。この 2 番目のサーフェスもカメラ プレビューの上に描画する必要がありますが、背景は透明です。私の現在の実装では、両方のサーフェス ビューが動作し、想定どおりに表示されていますが、背景が透明ではないため、カメラ プレビュー サーフェス ビューに重ねて描画されたグラフィックスを含む 2 番目のサーフェス ビューは表示されません。これはどのように達成できますか?多数のスタック オーバーフローの質問や他のフォーラムを検索すると、この問題に関して多くの矛盾する意見に出会いました。Android でサーフェス ビューをレイヤー化することは不可能だと言う人もいれば、別のレイアウトを使用することの問題だと言う人もいます (FrameLayout と LinearLayout?) 具体的には、私の実装には、SurfaceView を拡張するクラス、CustomCameraView、およびクラスの 2 つのビューが含まれます。 、CustomDrawView も FrameLayout に含まれる SurfaceView を拡張し、CustomDrawView は CustomCameraView の後に表示されます。CustomDrawView が CustomCameraView に重なっているように見えるように、これらをどのように階層化できますか? また、FrameLayout に含まれる SurfaceView を拡張し、CustomDrawView を CustomCameraView の後に表示します。CustomDrawView が CustomCameraView に重なっているように見えるように、これらをどのように階層化できますか? また、FrameLayout に含まれる SurfaceView を拡張し、CustomDrawView を CustomCameraView の後に表示します。CustomDrawView が CustomCameraView に重なっているように見えるように、これらをどのように階層化できますか?

4

2 に答える 2

9

多くの人がこれを試したと思います。Google Engineeは(ここで)SurfaceViewsのスタックを避けるべきであると明確に述べました。誰かがそれを行うためのトリックを見つけたとしても、それはおそらく互換性がなく、問題につながるでしょう。

要件に応じて、これには3つのオプションがあると思います。

  • サーフェスビューの上部に表示

カメラプレビューにサーフェスビューを使用し、その上にビューをスタックします。このアプローチの欠点は、「通常の」ビューでの描画がa)遅く、b)UIスレッドで行われることです。スレッドを自分で実装する場合は、b)を回避できます。ただし、一般的に、オーバーレイにUI要素や、頻繁に更新する必要のないいくつかのDrawableのようなものが含まれている場合は、これがおそらく最適な方法です。

  • SurfaceViewですべてを行う

これにより、実行時のパフォーマンスが向上し、オーバーヘッドが減少します。SurfaceViewは1つだけです。SurfaceViewにオーバーレイを合成し、そこにすべてを描画します。もちろん、両方のアプローチを組み合わせることができます。

  • GLSurfaceViewですべてを行う

これはおそらく実際のパフォーマンスを実現するための方法です。上記と同様ですが、 GLSurfaceViewのOpenGLテクスチャへのカメラビューレンダリングを使用します。

于 2011-02-15T23:25:20.970 に答える
2

次のアプローチを使用して、カメラのSurfaceViewの上に2つの透明なビューを作成して、これを機能させました。

私のアクティビティはメソッド内のすべてのビューを設定します。そのonCreate()ためのレイアウト ファイルは使用しません。次のようになります。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(null); //savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    cameraPreview = new CameraPreview(this);
    addContentView(cameraPreview, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

    animationView = new AnimationView(this);
    addContentView(animationView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

    crosslinesView = new CrosslinesView(this);
    addContentView(crosslinesView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}

cameraPreviewはタイプSurfaceViewanimationViewありcrosslinesViews、タイプはViewです。後者onDraw()の 2 つのビューは次のようになります。

protected void onDraw(Canvas canvas) {
    // Have the view being transparent
    canvas.drawARGB(0, 0, 0, 0);
    // Your drawing code goes here
    // ...
}

幸運を!

于 2011-02-11T06:51:19.880 に答える