TextureView

TextureView 是什么

 TextureView 是一个由于显示数据流的UI控件。从这里我们不难得知TextureView的应用场景应该主要分为两种:
1:播放视频
2:显示相机预览

 TextureView既然作为一个控件,那么可以像普通的控件一样进行布局、动画等设置。

TextureView 的优点

可以当做普通的View控件使用,在布局、动画和变换(平移、缩放、旋转等)中非常方便

TextureView 的缺点

由于TextureView是作为普通控件使用,那么所处理的数据流也都在APP的主线程进行处理,会比较占用内存

TextureView 的使用

在相机中使用

我们以在相机(Camera2)中的应用为例进行代码介绍
在xml布局文件中添加该控件(和普通控件的处理方式相同)

<TextureView
        android:id="@+id/texture_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

在Android代码中获取控件,并设置监听来处理当前显示预览的SurfaceTexture状态

   private TextureView mTextureView;
   private CameraManager mCameraManager;
   private List<String> mBackCameraList = new ArrayList();

   @Override
   protected void onCreate(@Nullable Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
       mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
       getAllBackCameraId();
   }

   /**
   * 获取后置相机sensor 列表
   */
   private void getAllBackCameraId() {
       try {
           for (String cameraId : mCameraManager.getCameraIdList()) {
               CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(cameraId);
               Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
               if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) {
                   mBackCameraList.add(cameraId);
               }
           }
       } catch (CameraAccessException e) {
           e.printStackTrace();
       }
   }

   private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener(){
       @Override
       public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
           initBackCamera();
       }

       @Override
       public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
       }

       @Override
       public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
           return false;
       }

       @Override
       public void onSurfaceTextureUpdated(SurfaceTexture surface) {
       }
   };

   /**
   *  进行相机的初始化配置
   */
   private void initBackCamera() {
       String cameraId = mBackCameraList.get(0); //只使用后置主摄
       try {
           CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(cameraId);
           StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
           
           Size[] sizes = map.getOutputSizes(ImageFormat.JPEG);
           Size largest = Collections.max(Arrays.asList(sizes), new CompareSizesByArea());
           ...
           进行一些配置工作
           ...
       } catch (CameraAccessException e) {
           e.printStackTrace();
       }
   }

具体后边的处理逻辑这里不再详细描述。
从上边的代码中我们可以了解,使用TextureView分为四步:
1:在布局文件中添加Textureview
2:在Activity中添加 SurfaceTextureListener 回调
3:在 onSurfaceTextureAvailable 回调中拿到SurfaceTexture;并将它设置给camera作为承载预览数据流的载体
4:在 onSurfaceTextureDestroyed 回调中做一些释放资源操作

在播放视频文件时使用

在xml中添加布局文件

<TextureView
        android:id="@+id/texture_view_play_video"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

在Activity中获得控件,并设置监听

private TextureView mTextureViewPlayVideo;
    private Surface mSurface;
    private MediaPlayer mMediaPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextureViewPlayVideo = findViewById(R.id.texture_view_play_video);
        mTextureViewPlayVideo.setSurfaceTextureListener(mSurfaceTextureListener);
    }

    private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            mSurface = new Surface(surface);
            playVideo();
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            surface = null;
            mSurface = null;
            mMediaPlayer.stop();
            mMediaPlayer.release();
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {

        }
    };

    private void playVideo() {
        try {
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDataSource(getAssets().openFd("testvideo.mp4"));
            mMediaPlayer.setSurface(mSurface);
            mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mMediaPlayer.start();
                }
            });
            mMediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

具体逻辑和在相机中使用方式几乎相同

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值