本文介绍了SurfaceView闪烁黑色负载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个绘图应用程序,大约需要2-5秒的负载进行复杂的图纸绘制(通过完成的AsyncTask )。为了更好的用户体验,在此期间,我闪存储PNG版本绘图我从app目录为的ImageView 中,并显示加载进度调用的setContentView()在活动构造:

I have a drawing app that takes about 2-5 seconds to load the drawing for complicated drawings (done via an AsyncTask). For a better user experience, during this time I flash the stored PNG version of the drawing I have from the app directory as an ImageView, and show a loading ProgressBar calling setContentView() in the Activity constructor:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
    android:id="@+id/flash"
    android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@color/note_bg_white"
        android:contentDescription="@string/content_desc_flash_img"
        android:focusable="false" />
<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="6dp"
        android:paddingLeft="6dp"
    android:paddingRight="6dp"
        android:gravity="bottom|center_vertical">
        <ProgressBar 
            style="?android:attr/progressBarStyleHorizontal"
    android:id="@+id/toolbar_progress"
    android:layout_width="match_parent"
    android:layout_height="18dp"
    android:gravity="bottom|center_vertical" />
    </RelativeLayout>
</FrameLayout>

的AsyncTask 完成后,我再调用的setContentView()再次与新的布局:

When the AsyncTask is complete, I then call setContentView() again with the new layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff">
    <com.my.package.DrawingCanvas
        android:id="@+id/canvas"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:focusable="true"
        android:background="#ffffff" />
</RelativeLayout>

当我使用一个简单的画布模式,这完美地工作,为自定义DrawingCanvas 查看将绘制用绘制到屏幕上的初始的OnDraw()显示给用户,但在此之前使用 SurfaceView 绘图循环,我看到了闪蒸布局,然后绘图时加载,黑屏大约一秒钟,然后终于在新DrawingCanvas。

When I was using a simple Canvas model, this worked perfectly, as the custom DrawingCanvas View would draw the drawing to the screen on the initial onDraw() before being shown to the user, but now using the SurfaceView with a drawing loop, I am seeing the flashed layout, then when the drawing is loaded, a black screen for about a second, then finally the new DrawingCanvas.

我假设的原因是相关的图纸循环线程的启动时间,我已经离开了我的超越控制的OnDraw() SurfaceView ,它被调用,但在的OnDraw可在画布()似乎并没有吸引到 SurfaceView 。我也试着设置纯色背景之上,希望至少显示白色背景上的XML,但那些似乎永远生效,甚至从code设置它。

I am assuming that the reason is related to the start-up time of the drawing loop thread, and I've left my overide of onDraw() in the SurfaceView, and it gets called, but the canvas available in onDraw() does not seem to draw to the SurfaceView. I've also tried setting a solid color background in the XML above hoping at a minimum to show a white background, but those never seem to take affect, even setting it from code.

任何意见或解释我所看到的黑屏?

Any advice or an explanation of what I am seeing with the black screen?

编辑:

确定,已经证实的OnDraw()被绘制为相同的画布,所以留下了我的拉伸OPS在那里,以及希望在SurfaceView的初始有显示,用户将看到的那些附图像在常规画布实施当绘图线程已经纺时,它会覆盖画布。

Ok, have confirmed that onDraw() is drawing to the same canvas, so left my draw ops in there as well hoping that on the initial showing of the SurfaceView, the user would see those drawings like in the regular Canvas implementation, and when the drawing thread had spun up, it would overwrite the Canvas.

不过,如果我清除绘图线程操作,我看到的OnDraw()的结果,但同样,黑屏后闪光。如果我删除的OnDraw()覆盖完全,我仍然看到了黑色的闪光,然后我看到了白色背景从XML布局。

However, if I clear the drawing thread operations, I do see the onDraw() results, but again, AFTER the black screen flash. And if I remove the onDraw() override completely, I still see the black flash and then I see the layout with the white background from the XML.

所以,它看起来像不管是什么,我总是会出现黑屏,而不是切换布局,除非也许,我只是修改现有的闪光的布局,已经是活动的?

So, it looks like no matter what, I am always going to see the black screen, unless perhaps instead of switching the layouts, I simply modify the existing 'flash' layout that is already active?

EDIT2:

使用 ViewStub 试过这样我就可以充气SurfaceView到现有的注释后视图被加载,但同样ISSU仍然适用。尽可能接近我可以告诉大家,有一个相当大的(〜200毫秒)的SurfaceView构造函数和调用surfaceCreated()之间的延迟执行,但不知道这是哪里的黑屏正在发生的事情,为什么屏幕被吸引到黑色...

Have tried using a ViewStub so that I can inflate the SurfaceView into the existing View after the note is loaded, but the same issu still applies. As near as I can tell, there is a sizable (~200ms) delay between the SurfaceView constructor and the call to surfaceCreated() executing, but not sure that this is where the black screen is happening, or why the screen is being drawn to black...

EDIT3:

我的最后一次尝试,现在包括制作的 SurfaceView透明。这种结合而使现有布局到位,只是增加了通过ViewStub该布局将导致一个可行的解决方案我虽然,不过,一秒钟时,SurfaceView加载黑色的屏幕上闪烁SurfaceView显示之前,为透明。如果任何人有任何其他想法去尝试,请张贴。

My final attempt for now includes making the SurfaceView transparent. This combined with leaving the existing layout in place and simply adding to that layout via the ViewStub would have resulted in a working solution I though, but still, for a split second when the SurfaceView is loading the screen flashes black before the SurfaceView is shown, as transparent. If anyone has any other ideas to try, please post them.

推荐答案

我想我找到了黑色闪光的原因。在我来说,我使用的是SurfaceView一个片段内动态添加该片段的一些动作之后的活动。在那一刻,我片段添加到活动中,屏幕闪烁黑色。我检查了的grep code的SurfaceView来源,这里是我发现:当表面视图显示在窗口的很拳头的时候,它要求窗口的参数变化,通过调用私有 IWindowSession.relayout (..)方法。这种方法给你一个新的框架,窗口,窗口的表面。我认为屏幕闪烁就在那一刻。

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.

解决的办法是pretty的简单:如果你的窗口已经有了合适的参数也不会刷新所有窗口的东西,画面不闪烁。最简单的解决方案是一个 0px 高度纯SurfaceView添加到您的活动的第一个布局。这将重新创建窗口的活动显示在屏幕上之前,当你设置你的第二个布局它只会继续使用窗口的当前参数。我希望这有助于。

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.

这篇关于SurfaceView闪烁黑色负载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-17 09:07