给surfaceview设置默认背景 阿里云播放器背景层问题
2017-05-23 18:58
309 查看
给surfaceview设置默认背景 阿里云播放器背景层问题
如下图那个播放器是个surfacevieww组成的,而要设置刚进来不是透明的,看到刚刚进入的那个activity页面,可以设置如下
//需要activity背景就设置为true 否则 false
mSurfaceView.setZOrderOnTop(true);
//mSurfaceView.setZOrderOnTop(true);
//this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
//mSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
//不过中间那句是OpenGl的,视情况使用,无用可注释掉了,也能实现了透明,但是GLSurfaceView就必须使用
![](https://img-blog.csdn.net/20170523185523790?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3VxaWxpYW5nYQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
以下是资料参考和原理解析:
参考资料来源自:http://blog.csdn.net/erone/article/details/46461513
最近搞视频通话,SurfaceView是必不可少的,由于启动视频要加载一些资源,比较耗时,会有1.2s黑屏的现象,为了改善用户体验,我们需要设置Activity的Theme为透明风格(QQ 也是如此),下面是我截取的日志,QQ和我们启动视频通话界面(Activity)所花费的时间:
Displayed com.xxx.xxx/.activity.voip.CallVoipVideoActivity: +491ms:接收视频邀请
Displayed com.xxx.xxxx/.activity.voip.CallVoipVideoActivity: +1s737ms:发起视频邀请(包括加载视频预览)
Displayed com.tencent.mobileqq/com.tencent.av.ui.AVActivity: +1s977ms :发起视频邀请(QQ加载的资源更多,故会稍微再慢点,不过差别不大)
查看后台日志,发现一直在GC,当时我以为内存泄露了,电脑卡的要死,Mat了半天。。。
问题来了,经测试发现,在视频预览出现时,经常界面上的按钮可见,但是包含SurfaceView的FrameLayout布局处却是透明的,尽管我在主Activity的根布局设置了默认背景,只要你嵌套了SurfaceView并且SurfaceView未加载进内容,就会出现这种问题。
主Activity的布局如下:
[html] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/a" >
<include layout="@layout/test1_item" />
</FrameLayout>
[html] view
plain copy
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/a" >
<include layout="@layout/test1_item" />
</FrameLayout>
其中,a是默认的背景图片,test1_item.xml是包含SurfaceView的子布局,如下:
[html] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
<?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" >
<FrameLayout
android:id="@+id/testFr"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="挂断" />
</RelativeLayout>
</FrameLayout>
[html] view
plain copy
<?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" >
<FrameLayout
android:id="@+id/testFr"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="挂断" />
</RelativeLayout>
</FrameLayout>
测试发现,在SurfaceView有内容加载进来之前,那部分一直是透明的,不管你根布局有木有设置默认背景。
关于这个问题的解释,我们需要去了解下SurfaceView及Activity的原理:可参照:http://www.2cto.com/kf/201303/196117.html(SurfaceView理解); http://blog.csdn href="http://lib.csdn.net/base/dotnet" target=_blank>.NET/qinjuning/article/details/7226787(关于Activity的原理)。
其中注意下两段话:
1、用来描述SurfaceView的Layer或者LayerBuffer的Z轴位置是小于用来其宿主Activity窗口的Layer的Z轴位置的,但是前者会在后者的上面挖一个“洞”出来,以便它的UI可以对用户可见。实际上,SurfaceView在其宿主Activity窗口上所挖的“洞”只不过是在其宿主Activity窗口上设置了一块透明区域。
2、DecorView类 :该类是PhoneWindow类的内部类,说明:
该类是一个FrameLayout的子类,并且是PhoneWindow的子类,该类就是对普通的FrameLayout进行功能的扩展,更确切点可以说是修饰(Decor的英文全称是Decoration,即“修饰”的意思),比如说添加TitleBar(标题栏),以及TitleBar上的滚动条等
。最重要的一点是,它是所有应用窗口的根View 。
解决办法就是动态添加SurfaceView,但是前提是要保证SurfaceView已经有我们所需要的内容;第二个解决办法可以为SurfaceView设置一个默认的背景,背景的设置可以参照:http://bbs.csdn.Net/topics/380141705,我们可以分析到:surfaceview默认是黑色的背景,所以使用SurfaceView要特别注意这个问题(你所要显示的可能会被覆盖等现象),下边这三行代码是设置surfaceView控件背景透明:
[java] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
this.setZOrderOnTop(true);
//this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
不过中间那句是OpenGl的,视情况使用,无用可注释掉了,也能实现了透明,但是GLSurfaceView就必须使用
[java] view
plain copy
this.setZOrderOnTop(true);
//this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
不过中间那句是OpenGl的,视情况使用,无用可注释掉了,也能实现了透明,但是GLSurfaceView就必须使用
注意:SurfaceView添加背景后,要掉用setZOrderOnTop(true)这个方法才能把我们的内容画上,要不然我们所绘制的内容就在背景后面了,被背景覆盖。另外,在ViewPage中用到SurfaceView时,它所取到的画布是整个程序的画布,也就是在某个Activity里调用ViewPage时,ViewPage里包含SurfaceView,当ViewPage显示此SurfaceView就切换到别的Activity,那么SurfaceView所画的图会覆盖该Activity的界面。
哥们发现我的程序上述两个方法都没办法解决,只能设置默认背景了,就是你启动的时候的背景,在style文件中修改:
[html] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
//黑屏问题
<style name="activityVoipVideoTransparentTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@drawable/voip_video_default_big</item>
<item name="android:windowContentOverlay">@null</item>
</style>
[html] view
plain copy
//黑屏问题
<style name="activityVoipVideoTransparentTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@drawable/voip_video_default_big</item>
<item name="android:windowContentOverlay">@null</item>
</style>
这样也能达到效果啦!不过如果要不黑屏,实质上还是要分析下到底是哪里的问题导致主线程较耗时,有些东西可以适当延后加载
如下图那个播放器是个surfacevieww组成的,而要设置刚进来不是透明的,看到刚刚进入的那个activity页面,可以设置如下
//需要activity背景就设置为true 否则 false
mSurfaceView.setZOrderOnTop(true);
//mSurfaceView.setZOrderOnTop(true);
//this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
//mSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
//不过中间那句是OpenGl的,视情况使用,无用可注释掉了,也能实现了透明,但是GLSurfaceView就必须使用
以下是资料参考和原理解析:
参考资料来源自:http://blog.csdn.net/erone/article/details/46461513
最近搞视频通话,SurfaceView是必不可少的,由于启动视频要加载一些资源,比较耗时,会有1.2s黑屏的现象,为了改善用户体验,我们需要设置Activity的Theme为透明风格(QQ 也是如此),下面是我截取的日志,QQ和我们启动视频通话界面(Activity)所花费的时间:
Displayed com.xxx.xxx/.activity.voip.CallVoipVideoActivity: +491ms:接收视频邀请
Displayed com.xxx.xxxx/.activity.voip.CallVoipVideoActivity: +1s737ms:发起视频邀请(包括加载视频预览)
Displayed com.tencent.mobileqq/com.tencent.av.ui.AVActivity: +1s977ms :发起视频邀请(QQ加载的资源更多,故会稍微再慢点,不过差别不大)
查看后台日志,发现一直在GC,当时我以为内存泄露了,电脑卡的要死,Mat了半天。。。
问题来了,经测试发现,在视频预览出现时,经常界面上的按钮可见,但是包含SurfaceView的FrameLayout布局处却是透明的,尽管我在主Activity的根布局设置了默认背景,只要你嵌套了SurfaceView并且SurfaceView未加载进内容,就会出现这种问题。
主Activity的布局如下:
[html] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/CODE_ico.png)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/a" >
<include layout="@layout/test1_item" />
</FrameLayout>
[html] view
plain copy
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/a" >
<include layout="@layout/test1_item" />
</FrameLayout>
其中,a是默认的背景图片,test1_item.xml是包含SurfaceView的子布局,如下:
[html] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/CODE_ico.png)
<?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" >
<FrameLayout
android:id="@+id/testFr"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="挂断" />
</RelativeLayout>
</FrameLayout>
[html] view
plain copy
<?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" >
<FrameLayout
android:id="@+id/testFr"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="挂断" />
</RelativeLayout>
</FrameLayout>
测试发现,在SurfaceView有内容加载进来之前,那部分一直是透明的,不管你根布局有木有设置默认背景。
关于这个问题的解释,我们需要去了解下SurfaceView及Activity的原理:可参照:http://www.2cto.com/kf/201303/196117.html(SurfaceView理解); http://blog.csdn href="http://lib.csdn.net/base/dotnet" target=_blank>.NET/qinjuning/article/details/7226787(关于Activity的原理)。
其中注意下两段话:
1、用来描述SurfaceView的Layer或者LayerBuffer的Z轴位置是小于用来其宿主Activity窗口的Layer的Z轴位置的,但是前者会在后者的上面挖一个“洞”出来,以便它的UI可以对用户可见。实际上,SurfaceView在其宿主Activity窗口上所挖的“洞”只不过是在其宿主Activity窗口上设置了一块透明区域。
2、DecorView类 :该类是PhoneWindow类的内部类,说明:
该类是一个FrameLayout的子类,并且是PhoneWindow的子类,该类就是对普通的FrameLayout进行功能的扩展,更确切点可以说是修饰(Decor的英文全称是Decoration,即“修饰”的意思),比如说添加TitleBar(标题栏),以及TitleBar上的滚动条等
。最重要的一点是,它是所有应用窗口的根View 。
解决办法就是动态添加SurfaceView,但是前提是要保证SurfaceView已经有我们所需要的内容;第二个解决办法可以为SurfaceView设置一个默认的背景,背景的设置可以参照:http://bbs.csdn.Net/topics/380141705,我们可以分析到:surfaceview默认是黑色的背景,所以使用SurfaceView要特别注意这个问题(你所要显示的可能会被覆盖等现象),下边这三行代码是设置surfaceView控件背景透明:
[java] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/CODE_ico.png)
this.setZOrderOnTop(true);
//this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
不过中间那句是OpenGl的,视情况使用,无用可注释掉了,也能实现了透明,但是GLSurfaceView就必须使用
[java] view
plain copy
this.setZOrderOnTop(true);
//this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
不过中间那句是OpenGl的,视情况使用,无用可注释掉了,也能实现了透明,但是GLSurfaceView就必须使用
注意:SurfaceView添加背景后,要掉用setZOrderOnTop(true)这个方法才能把我们的内容画上,要不然我们所绘制的内容就在背景后面了,被背景覆盖。另外,在ViewPage中用到SurfaceView时,它所取到的画布是整个程序的画布,也就是在某个Activity里调用ViewPage时,ViewPage里包含SurfaceView,当ViewPage显示此SurfaceView就切换到别的Activity,那么SurfaceView所画的图会覆盖该Activity的界面。
哥们发现我的程序上述两个方法都没办法解决,只能设置默认背景了,就是你启动的时候的背景,在style文件中修改:
[html] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/CODE_ico.png)
//黑屏问题
<style name="activityVoipVideoTransparentTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@drawable/voip_video_default_big</item>
<item name="android:windowContentOverlay">@null</item>
</style>
[html] view
plain copy
//黑屏问题
<style name="activityVoipVideoTransparentTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@drawable/voip_video_default_big</item>
<item name="android:windowContentOverlay">@null</item>
</style>
这样也能达到效果啦!不过如果要不黑屏,实质上还是要分析下到底是哪里的问题导致主线程较耗时,有些东西可以适当延后加载
相关文章推荐
- 给surfaceview设置默认背景
- UITableView Grouped风格时,设置背景颜色的问题
- 关于surfaceview画背景格的几个问题
- 设置SurfaceView 背景颜色
- Android中Recyclerview使用9----Recyclerview的条目复用,出现CheckBox或者设置背景混乱问题
- 1016-06-首页20-封装工具条---UITableView控件距离顶部的间距问题----cell选中时的背景颜色设置
- 设置UITableview默认的背景和选择的背景
- 关于UITableView设置背景颜色无效的问题
- UIKit和Cocos2d-x的整合使用;设置CCEAGLView背景为透明,来显示背后的UIView; 以及整合中遇到的问题的解决方案
- android 5.0 默认水波纹背景属性,可设置任何View
- RecyclerView 复用出现 CheckBox 或者 设置背景混乱问题
- SurfaceView使用canvas来画图时设置背景透明
- SurfaceView中设置背景透明
- Android ScrollView添加SurfaceView背景问题
- 设置android SurfaceView背景透明
- 设置SurfaceView 背景为透明
- 设置surfaceView的背景为透明
- android开发之设置继承自SurfaceView的类的背景为透明
- SurfaceView设置背景后的无法绘图的解决方案
- 安卓4.0后新控件TextureView解决SurfaceView在修改默认屏幕方向后视频方向无法翻转的问题