文档章节

被SurfaceView搞死了的搞后感

拉风的道长
 拉风的道长
发布于 2016/09/20 20:21
字数 466
阅读 180
收藏 1

这几天遇到一个问题:

视频播放时,为了保持视频的宽高比,就需要在surfaceView的父view的大小改变的时候,改变SurfaceView的大小。

父View的大小改变的时候,会走View的onSizeChanged回调。所以,复写了这个方法:

 @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        Log.d(TAG, "onSizeChanged w = " + w + " , h = " + h + " , oldw = " + oldw + " , oldh = " + oldh);
        //当界面大小有变化的时候,需要改变surfaceView的大小。
        resizeSurfaceView();
    }

private void resizeSurfaceView()
{
     int width = mediaPlayer.getVideoWidth();
     int height = mediaPlayer.getVideoHeight();
//根据视频宽高和父View的宽高计算SurfaceView的宽高
     Point surfaceViewSize = measureSurfaceViewSize(width, height);
     RelativeLayout.LayoutParams surfaceLayoutParams = (LayoutParams) mSurfaceView.getLayoutParams();

     surfaceLayoutParams.width = surfaceViewSize.x;
     surfaceLayoutParams.height = surfaceViewSize.y;

     Log.d("size", " new size = " + surfaceViewSize);
     surfaceLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
//重新设置布局
     mSurfaceView.setLayoutParams(surfaceLayoutParams);
}

//根据视频宽高和父View的宽高计算SurfaceView的宽高
  private Point measureSurfaceViewSize(int width, int height) {
        float parentWh = getMeasuredWidth() * 1.0f / getMeasuredHeight();
        float videoWh = width * 1.0f / height;
        Point surfaceViewSize = new Point();
        if (parentWh >= videoWh) {
            surfaceViewSize.y = getMeasuredHeight();
            surfaceViewSize.x = (int) (surfaceViewSize.y * videoWh);
        } else {
            surfaceViewSize.x = getMeasuredWidth();
            surfaceViewSize.y = (int) (surfaceViewSize.x / videoWh);
        }

        return surfaceViewSize;
    }

结果在运行的时候发现,有时候设置了大小,但是SurfaceView的大小还是没有变化。

在网络上一片寻找,终于找到原因:SurfaceView在setLayoutParams之后,并不一定是立即生效的。生效时间取决于调用它的方法还要做多久。如果时间长了,可能就不会变大小了。

于是很简单的改了一下:

 @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        Log.d(TAG, "onSizeChanged w = " + w + " , h = " + h + " , oldw = " + oldw + " , oldh = " + oldh);
        //当界面大小有变化的时候,需要改变surfaceView的大小。

        //post是为了防止修改surfaceView的宽高导致的阻塞,从而导致转屏时出问题.
        this.post(new Runnable() {
            @Override
            public void run() {
                resizeSurfaceView();
            }
        });
    }

将resizeSurfaceView()方法,通过post跑一遍。这样就不会有问题了!

我花了一天的时间去找解决办法,没想到是它搞的鬼!

© 著作权归作者所有

共有 人打赏支持
拉风的道长
粉丝 54
博文 110
码字总数 55629
作品 0
昌平
程序员
私信 提问
C++还活着, 搞C++的差不多都死了 -- 两个凡是

搞C++的都被C++搞死了 C++没死 因为还有小鲜肉继续往火坑跳

宏哥
2016/09/29
1K
12
ASP.NET 制作WORD简历

最近公司在做一个项目,需要制作类似于人才网站word简历。 搞的我头疼死了,不知道该怎么搞。 我目前采用的是 Aspose.Words 制作,相当的不灵活。

Mr_Yang
2013/01/11
128
0
elasticsearch真是坑

搜索商品的功能。产品单纯的想实现一个like的功能。而有些人就喜欢搞分词。好像不搞分词搜索就显得不够高大上。这下好了,要实现like的功能要在elasticsearch里面加不分词的字段,再全量同步...

喜之郎
2017/02/15
483
5
HTML文件中loose.dtd的含义

上面这两行具体到HTML文件中,会有什么样的区别?曾经碰到过一次用第一行有问题,第二行就正常的问题,搞死了都快,但是至今未能搞明白这其中的原因。 请赐教!

陈老师1
2014/04/20
1K
2
刚接触jfinal 各种.NoClassDefFoundError

快被它搞死了。。。

y_y小样
2016/08/31
149
1

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot 集成 Swagger,生成接口文档就这么简单!

之前的文章介绍了《推荐一款接口 API 设计神器!》,今天栈长给大家介绍下如何与优秀的 Spring Boot 框架进行集成,简直不能太简单。 你所需具备的基础 告诉你,Spring Boot 真是个牛逼货! ...

Java技术栈
29分钟前
3
0
一个简单的js作用域题目(原创)

var name = 'nnmm' var obj = { name: 'name1', func: () => { console.log(this.name) }, func1: function (){ console.log(this.name) }, son: { ......

boogoogle
31分钟前
2
0
SSM整合activeMQ/activeMQ配置

一、引入依赖 <!-- xbean 如<amq:connectionFactory /> -->    <dependency>        <groupId>org.apache.xbean</groupId>        <artifactId>xbean-spring</artifac......

嘴角轻扬30
35分钟前
2
0
小公司出身的程序员,面试咋这么难?!

小公司出身,被大厂竞争者 KO 以下是一个非常真实的案例,是一个大厂工程师和一个小公司工程师同时求职一个独角兽公司的职位的经历。 一个是985本科学历,出身互联网大厂,四五年经验的样子。...

编程SHA
41分钟前
2
0
揭秘:蚂蚁金服bPaaS究竟是什么?

摘要: 分布式金融核心套件,蚂蚁金服bPaaS究竟是什么东东? 文/图 孙浩峰 去年9月,蚂蚁金服在杭州云栖ATEC发布了分布式金融核心套件bPaaS( Business Platform As a Service ),对外开放自...

阿里云官方博客
42分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部