天天看点

安卓4.0后新控件TextureView解决SurfaceView在修改默认屏幕方向后(硬件导致)视频方向无法翻转的问题

问题:

  之前做东西的时候一直用SurfaceView来作为视频播放的控件载体,而前些时候客户突然出了这么一个新需求:用户期望能够为竖屏适配一套UI,同时将默认方向改为竖屏。但在修改了系统默认屏幕方向且为竖屏匹配了一套UI(JSON)后,除了SurfaceView播放视频还是横向外,其他的控件都可以变成竖向。

相关知识梳理:

  • 要修改系统默认屏幕方向为竖屏:

      可以通过修改/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java中的rotationForOrientationLw(int,int)的返回值来实现默认界面方向的修改。重新在/frameworks/base/policy下编译(mm语句)得到android.policy.jar文件,将其复制到系统/system/framework/目录下,注意保持.jar文件与目录下其他文件的权限一致,然后重启,妥了。如果有不懂的,可以自己搜索学习

这位仁兄的做法确实值得学习–http://blog.csdn.net/weed_hz/article/details/22407575

如果不喜欢或者不熟悉底层的话,那我们还是学习一下如我以上所说的做法吧–http://blog.csdn.net/wh_19910525/article/details/37963375

  • 现在的问题是,当进入应用后,图片、字幕、类ViewPager自定义控①(如果有人想要代码,可以在之后的文章里分享一下)的方向都变成了竖向,仅视频的显示仍然是横向的。

①:可设置上下或左右定时滑动、多行多列图片以及根据控件属性自动设置页数等功能,滑动是以每个图片为单位而非整体滑动,可在任何时间动态刷新图片资源并且能及时释放不必要的资源,根据情况在保证图片质量的情况下优化操作图片以防止图片过大产生OutOfMemoryError而不是加载显示图片…

解决:

  • 将原本的 SurfaceView换成TextureView之后,视频翻转的问题终于得以解决。如果大家想了解一下SurfaceView和TextureView究竟有什么不同之处,可以看源码或者去下面提到的地方学习
Android 5.0(Lollipop)中的SurfaceTexture,TextureView, SurfaceView和GLSurfaceView–http://www.bubuko.com/infodetail-656030.html

  

  • TextureView的用法:
TextureView sfv = new TextureView(mContext);
sfv.setKeepScreenOn(true);
sfv.setLayerType(TextureView.LAYER_TYPE_SOFTWARE, null);//防止出现一些莫名奇妙的问题出现
sfv.setSurfaceTextureListener(new MyListener());
private class MyListener implements SurfaceTextureListener {

        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int size) {
            Log.i("onSurfaceTextureAvailable","onSurfaceTextureAvailable");
            mSurface = new Surface(texture);//此对象为全局变量,直接与MMediaPlayer对象相关
            MMediaPlayer.getInstance().setSurface(mSurface);
            isSurfaceCreated = true;
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
            Log.i("onSurfaceTextureDestroyed","onSurfaceTextureDestroyed");
            isSurfaceCreated = false;
            mSurface.release();
            mSurface.destroy();
            texture.release();
            return false;
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture arg0, int arg1, int arg2) {
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture arg0) {
        }
    }
           

  其实和SurfaceView的用法很像,但要是没有TextureView怎么办呢?这个时候,其实就可以通过两个控件源码的阅读和对比解读了。其实也算是各有优劣吧

  最后,给大家介绍两篇文章,我觉得写的挺好的:

Android TextureView简易教程

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1213/2153.html

在Chromium for Android中能否用TextureView替代SurfaceView

http://www.th7.cn/Program/Android/201506/486296.shtml