Видеофрагмент внутри фрагмента вызывает черный экран

У нас есть Android-приложение, работающее на Android API 4.0. Один из видов деятельности имеет макет, который делит экран на 2 части. С левой стороны у нас есть статическая часть с некоторыми кнопками. С правой стороны у нас есть FrameLayout, который переключится на соответствующий фрагмент в зависимости от нажатой кнопки.

Проблема. Один из фрагментов с правой стороны содержит 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, мерцание исчезло.

Solutions Collecting From Web of "Видеофрагмент внутри фрагмента вызывает черный экран"

Я смог исправить это, добавив 0px на 0px SurfaceView в макет родительской активности фрагмента:

 <SurfaceView android:layout_width="0px" android:layout_height="0px" /> 

KennyDs прав, но лучше спрячьте SurfaceView, иначе у вас будет действительно странное поведение, если вы будете анимировать фрагменты, тогда вместо анимированного фрагмента вы не увидите ничего, кроме черного экрана. К счастью, эта проблема с обеспечением также имеет легкое исправление:

 <SurfaceView android:layout_width="0px" android:layout_height="0px" android:visibility="gone" /> 

Если вам интересно, почему добавление нулевого размера SurfaceView решает проблему, вы можете взглянуть на этот вопрос. SurfaceView мигает черным при загрузке . Это хорошо объясняет.

Цитата из ответа Evos

Когда представление поверхности появляется в окне в самое первое время, оно запрашивает изменение параметров окна, вызывая частный метод IWindowSession.relayout (..). Этот метод «дает» вам новый кадр, окно и поверхность окна. Я думаю, что в этот момент экран мигает. Решение довольно простое: если у вашего окна уже есть соответствующие параметры, он не обновит все материалы окна, и экран не будет мигать. Простейшим решением является добавление SurfaceView высотой 0px в первый макет вашей деятельности. Это приведет к воссозданию окна до того, как действие будет показано на экране, а когда вы установите второй макет, он просто продолжит использование окна с текущими параметрами.

И вот более чистый способ решить эту проблему, вызовите это, прежде чем вы вызовите setContentView (), просто протестированный на моем ViewPager с некоторыми фрагментами, содержащими VideoView, он работает так же хорошо, как добавление SurfaceView нулевого размера:

 getWindow().setFormat(PixelFormat.TRANSLUCENT); 

Просто добавьте прозрачный цвет фона VideoView . Это решит проблему.

 android:background="@color/transparent"