21

Android API 4.0 で実行されている Android アプリケーションがあります。アクティビティの 1 つに、画面を 2 つの部分に分割するレイアウトがあります。左側には、いくつかのボタンを備えた静的な部分があります。右側には、押されたボタンに応じて対応するフラグメントに切り替わる FrameLayout があります。

問題: 右側のフラグメントの 1 つに VideoView が含まれています。ユーザーがボタンをクリックしてこのフラグメントを表示すると、フラグメントが表示され、すぐにビデオの再生が開始されます。ただし、このフラグメントをレンダリングすると、画面全体が黒くちらつき、非常に煩わしくなります。

VideoFragment クラスのコードを次に示します。

public class VideoFragment extends Fragment {

    public VideoView videoView;

    private ExternalVideo mVideo;
    private boolean mVideoExists;
    private String mDestination;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mDestination = ApplicationParams.MEDIA_STORAGE_PATH + "videos/"
                + FilenameUtils.getBaseName(((DetailActivity)getActivity()).getProduct().getVideoUrl())
                + "."
                + FilenameUtils.getExtension(((DetailActivity) getActivity()).getProduct().getVideoUrl());

        File file = new File(mDestination);
        mVideoExists = file.exists() && file.isFile();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view;

        if (mVideoExists) {
            getActivity().getWindow().setFormat(PixelFormat.TRANSLUCENT);
            view = inflater.inflate(R.layout.video, null);
            mVideo = new ExternalVideo(mDestination);

            videoView = (VideoView) view.findViewById(R.id.video_video);

            MediaController mediaController = new MediaController(getActivity());
            mediaController.setAnchorView(videoView);

            videoView.setMediaController(mediaController);
            videoView.setVideoPath(mVideo.getFullPath());
            videoView.requestFocus();
            videoView.setVisibility(View.VISIBLE);

            videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                public void onPrepared(MediaPlayer mp) {
                    videoView.start();

                }
            });
        } else {
            TextView textView = new TextView(getActivity());
            textView.setText(getActivity().getString(R.string.videofragment_video_coming_soon));
            textView.setPadding(50, 50, 50, 50);
            view = textView;
        }

        return view;
    }

}

ビデオフラグメントのレイアウトは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <VideoView android:id="@+id/video_video"
               android:layout_width="fill_parent"
               android:layout_alignParentRight="true"
               android:layout_alignParentLeft="true"
               android:layout_alignParentTop="true"
               android:layout_alignParentBottom="true"
               android:layout_height="fill_parent"/>
</RelativeLayout>

VideoView を含むフラグメントをレンダリングする際に、このちらつきの問題を引き起こしている原因を知っている人はいますか? 解決策をいただければ幸いです。

EDIT1: VideoView が画面上にあるフラグメントをクリックすると、最初にちらつきます。その後、別のフラグメントに移動し、VideoView を含むフラグメントに戻ると、ちらつきがなくなります。

4

4 に答える 4

13

KennyDs は正しいですが、必ず SurfaceView を非表示にしてください。そうしないと、フラグメントをアニメーション化すると非常に奇妙な動作が発生し、アニメーション化されたフラグメントの代わりに黒い画面しか表示されなくなります。幸いなことに、この副次的な問題も簡単に修正できます。

<SurfaceView
    android:layout_width="0px"
    android:layout_height="0px"
    android:visibility="gone" />
于 2014-04-10T17:46:23.287 に答える
4

サイズがゼロの SurfaceView を追加すると問題が解決する理由がわからない場合は、この質問SurfaceView flashes black on load を参照してください。それはよく説明します。

Evosの回答から引用

サーフェス ビューがウィンドウに最初に表示されると、プライベート IWindowSession.relayout(..) メソッドを呼び出して、ウィンドウのパラメーターの変更を要求します。このメソッドは、新しいフレーム、ウィンドウ、およびウィンドウ サーフェスを「提供」します。その瞬間に画面が点滅すると思います。解決策は非常に簡単です。ウィンドウに適切なパラメーターが既にある場合、ウィンドウのすべてのものは更新されず、画面は点滅しません。最も簡単な解決策は、高さ 0px のプレーンな SurfaceView をアクティビティの最初のレイアウトに追加することです。これにより、アクティビティが画面に表示される前にウィンドウが再作成され、2 番目のレイアウトを設定すると、現在のパラメーターでウィンドウが引き続き使用されます。

そして、これはこの問題を解決するためのよりクリーンな方法です。setContentView() を呼び出す前にこれを呼び出します。VideoView を含むいくつかのフラグメントを使用して ViewPager でテストしたところ、サイズがゼロの SurfaceView を追加するのと同じくらいうまく機能します。

getWindow().setFormat(PixelFormat.TRANSLUCENT);
于 2016-05-26T23:03:37.240 に答える
-4

の透明な背景色を追加するだけですVideoView。それは問題を解決します。

android:background="@color/transparent"
于 2015-09-10T10:00:45.557 に答える