Pau*_*ega 32 android surfaceview android-canvas
我有一个绘图应用程序需要大约2-5秒来加载复杂图纸的绘图(通过一个完成AsyncTask).为了获得更好的用户体验,在此期间我将应用程序目录中存储的PNG版本作为一个闪存ImageView,并在Activity构造函数中显示加载ProgressBar调用setContentView():
<?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>
Run Code Online (Sandbox Code Playgroud)
当AsyncTask完成后,我再调用setContentView()的新布局再次:
<?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>
Run Code Online (Sandbox Code Playgroud)
当我使用一个简单的Canvas模型时,这非常有效,因为自定义DrawingCanvas View会onDraw()在向用户显示之前将绘图绘制到初始屏幕上,但现在使用SurfaceView带有绘图循环,我看到闪烁的布局,然后加载图形时,黑屏大约一秒钟,最后是新的DrawingCanvas.
我假设原因与绘制循环线程的启动时间有关,并且我已经离开了我onDraw()的内部SurfaceView,并且它被调用,但是可用的画布onDraw()似乎没有绘制到SurfaceView.我也尝试在XML中设置纯色背景,希望至少能够显示白色背景,但这些背景似乎永远不会生效,甚至从代码设置它.
我对黑屏的看法有什么建议或解释吗?
编辑:
好的,已经确认onDraw()正在绘制到同一个画布,所以在那里留下我的绘制操作以及希望在初始显示SurfaceView时,用户会看到像常规Canvas实现中的那些绘图,以及绘制线程已经旋转,它将覆盖Canvas.
但是,如果我清除了绘图线程的操作,我确实看到了onDraw()的结果,但是再次,黑屏闪烁之后.如果我完全删除onDraw()覆盖,我仍然会看到黑色闪光,然后我看到XML中带有白色背景的布局.
所以,看起来无论如何,我总是会看到黑屏,除非可能不是切换布局,我只是修改已经激活的现有"闪存"布局?
EDIT2:
尝试过使用ViewStub,这样我可以在加载音符后将SurfaceView充气到现有的View中,但同样的issu仍然适用.就像我所知,SurfaceView构造函数和对surfaceCreated()执行的调用之间有一个相当大的(约200ms)延迟,但不确定这是黑屏发生的原因,或者为什么屏幕被绘制到黑色...
EDIT3:
我现在的最后一次尝试包括使SurfaceView透明化.这与现有的布局相结合,只需通过ViewStub添加到该布局就可以得到一个可行的解决方案,但是,当SurfaceView加载时,在SurfaceView显示之前,屏幕闪烁黑色,透明的.如果有人有任何其他想法尝试,请发布它们.
Evo*_*vos 147
我想我找到了黑色闪光的原因.在我的情况下,我在Fragment中使用SurfaceView,并在执行某些操作后动态地将此片段添加到活动中.当我将片段添加到活动时,屏幕闪烁黑色.我检查了SurfaceView源代码的grepcode,这就是我发现的:当窗口中的表面视图出现时,它会通过调用私有IWindowSession.relayout(..)方法来请求窗口的参数发生变化.此方法"为您提供"新的框架,窗口和窗口表面.我觉得那一刻屏幕正好闪烁.
解决方案非常简单:如果您的窗口已经有适当的参数,它将不会刷新所有窗口的东西,屏幕也不会闪烁.最简单的解决方案是将0px高度平面SurfaceView 添加到活动的第一个布局中.这将在屏幕上显示活动之前重新创建窗口,当您设置第二个布局时,它将继续使用具有当前参数的窗口.我希望这有帮助.
更新:看起来多年后这种行为仍然存在.我建议使用TextureView而不是SurfaceView.这实际上是一种新的实现同样的事情,没有这种副作用,以及当你(滚动型,ViewPager,RecyclerView等内例如)移动它没有黑色背景的问题.
我不会用两个单独的布局来做这个.
尝试将您的根元素设置为RelativeLayout,然后使SurfaceView和ImageView成为兄弟姐妹.无论您的线程等发生什么,ImageView都应该在SurfaceView顶部绘制完全不透明,因此您不会获得闪光.
一旦您的工作线程加载了图形并且SurfaceView可以自行绘制,请从视图层次结构中删除进度条和ImageView.
“ onDraw() 中可用的画布似乎没有绘制到 SurfaceView” - 您确定不创建 Surface View 的第二个(或第三个......)实例吗?其中一些可能是黑色的并显示一秒钟。我在这里看不到代码,所以,我不能确定,但如果它在我的应用程序中,我会首先检查此错误。
| 归档时间: |
|
| 查看次数: |
19731 次 |
| 最近记录: |