SurfaceView flashes black on load

风格不统一 提交于 2019-11-26 23:53:14

I think I found the reason for the black flash. In my case I'm using a SurfaceView inside a Fragment and dynamically adding this fragment to the activity after some action. The moment when I add the fragment to the activity, the screen flashes black. I checked out grepcode for the SurfaceView source and here's what I found: when the surface view appears in the window the very fist time, it requests the window's parameters changing by calling a private IWindowSession.relayout(..) method. This method "gives" you a new frame, window, and window surface. I think the screen blinks right at that moment.

The solution is pretty simple: if your window already has appropriate parameters it will not refresh all the window's stuff and the screen will not blink. The simplest solution is to add a 0px height plain SurfaceView to the first layout of your activity. This will recreate the window before the activity is shown on the screen, and when you set your second layout it will just continue using the window with the current parameters. I hope this helps.

UPDATE: Looks like after years this behavior is still there. I would recommend to use TextureView instead of SurfaceView. This is literally a newer implementation of same thing that don't have this side effect as well as don't have a problem of black background when you moving it (for instance within ScrollView, ViewPager, RecyclerView etc).

I would not do this with two separate layouts.

Try making your root element a RelativeLayout and then having the SurfaceView and ImageView be sibling children of that. Whatever happens with your threading etc, the ImageView should be drawn wholly opaque on top of the SurfaceView, so you won't get a flash.

Once your worker thread has loaded the drawing and the SurfaceView can draw itself, remove the progress bar and ImageView from the view hierarchy.

Tofeeq Ahmad

I assume that you're drawing some heavy code in your surface view because as far as I know, the surface view will show the complete view after drawing everything one time. I suggest you first go to the onDraw() method of surface view then set on background of canvas then call forcefully invalidate to avoid that black screen. Add a condition to be sure that this forcefully invalidate is only called once.

You need to make sure that onSurfaceChanged() doesn't return until you have completely drawn and posted the contents of the SurfaceView's Surface.

Valentin Baryshev

If you use NavigationDrawer with fragments, than Evos solution will not work!
Try to use NavigationDrawer with Activities instead of fragments, this will help you 100%

How to implement NavDrawer with activities: link
Another helpful link. (in case of SurfaceView will draw on top of SlidingMenu)

" the canvas available in onDraw() does not seem to draw to the SurfaceView" - Are you sure that you do not create the second (or third...) instance of the Surface View? And some of them could be black and be shown for a second. I don't see the code here, so, I can't tell surely, but if it were in my application, I would check for this error at first.

I facing the same issue but thank for this answer

There is a less messy approach, just put getWindow().setFormat(PixelFormat.TRANSLUCENT); in the host activity's onCreate() callback before calling setContentView().

CrazyOrr's solution worked for me, but it was deep in the comments for the top answer by Evos, so here it is again:

There is a less messy approach, just put getWindow().setFormat(PixelFormat.TRANSLUCENT); in the host activity's onCreate() callback before calling setContentView(). – CrazyOrr May 5 '16 at 7:29

Simply putting

getWindow().setFormat(PixelFormat.TRANSLUCENT); 

in the activity's onCreate() worked for me.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!