片段内的VideoView导致黑屏闪烁



我们有一个在Android API 4.0上运行的Android应用程序。其中一个活动的布局将屏幕分为两部分。在左侧,我们有一个带有一些按钮的静态部分。在右侧,我们有一个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的片段时,闪烁消失了。

我能够通过在片段的父活动的布局中添加一个0px乘0px的SurfaceView来解决这个问题:

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

KenneyDs是对的,但最好确保隐藏SurfaceView,否则如果你为片段设置动画,你会有非常奇怪的行为,那么你只会在动画片段的位置看到黑屏。幸运的是,这个附带问题也有一个简单的解决方案:

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

如果您想知道为什么添加零大小的SurfaceView可以解决问题,可以看看这个问题SurfaceView在加载时会闪烁黑色。它解释得很好。

引用自Evos的回答

当曲面视图第一次出现在窗口中时,它会通过调用专用IWindowSession.reayout(..)方法来请求更改窗口的参数。此方法为您"提供"一个新的框架、窗口和窗口曲面。我认为屏幕在那一刻闪烁着。解决方案很简单:如果你的窗口已经有了合适的参数,它就不会刷新窗口的所有内容,屏幕也不会闪烁。最简单的解决方案是在活动的第一个布局中添加一个0px高的平面SurfaceView。这将在活动显示在屏幕上之前重新创建窗口,当您设置第二个布局时,它将继续使用具有当前参数的窗口。

这里有一个更干净的方法来解决这个问题,在调用setContentView()之前先调用它,刚刚在我的ViewPager上测试了一些包含VideoView的片段,它的效果就像添加零大小的SurfaceView:一样好

getWindow().setFormat(PixelFormat.TRANSLUCENT);

只需添加VideoView的透明背景色即可。它将解决问题。

android:background="@color/transparent"

最新更新