TextureView在4.0(API level 14)中引入。它能够将内容流直接投影到View中,能够用于实现Live preview等功能。和SurfaceView不一样,它不会在WMS中单首创建窗口,而是做为View hierachy中的一个普通View,所以能够和其它普通View同样进行移动,旋转,缩放,动画等变化。值得注意的是TextureView必须在硬件加速的窗口中。它显示的内容流数据能够来自App进程或是远端进程。从类图中能够看到,TextureView继承自View,它与其它的View同样在View hierachy中管理与绘制。TextureView重载了draw()方法,其中主要把SurfaceTexture中收到的图像数据做为纹理更新到对应的HardwareLayer中。SurfaceTexture.OnFrameAvailableListener用于通知TextureView内容流有新图像到来。SurfaceTextureListener接口用于让TextureView的使用者知道SurfaceTexture已准备好,这样就能够把SurfaceTexture交给相应的内容源。Surface为BufferQueue的Producer接口实现类,使生产者能够经过它的软件或硬件渲染接口为SurfaceTexture内部的BufferQueue提供graphic buffer。html
结构类图以下java
这里不啰嗦解释,具体看官方API文档android
Textureview APIcanvas
自定义一个view,注意TextureView中的draw方法和onDraw方法都是被定义成final的,不能被子类覆盖。因此必须能够经过实现TextureView.SurfaceTextureListener 接口,而后重写onSurfaceTextureAvailable方法,把你想添加的功能加到这个方法里便可,这里加入播放视频的功能markdown
package com.test.xingliu.texturesample;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.view.Surface;
import android.view.TextureView;
import java.io.IOException;
/** * Created by Xingliu on 2016/12/5. */
public class MainView extends TextureView implements TextureView.SurfaceTextureListener {
private static final String FILE_NAME = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";
private MediaPlayer mMediaPlayer;
public MainView(Context context) {
super(context);
initView();
}
public void stopPlay() {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
}
private void initView() {
setSurfaceTextureListener(this);
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) {
Surface surface = new Surface(surfaceTexture);
try {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(FILE_NAME);
mMediaPlayer.setSurface(surface);
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mMediaPlayer.start();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i2) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
}
对应的activity_main.xml网络
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="176dp"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<com.test.xingliu.texturesample.MainView
android:id="@+id/textureView"
android:layout_width="match_parent"
android:layout_height="176dp"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin" />
</LinearLayout>
package com.test.xingliu.texturesample;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MainView(this));
}
@Override
protected void onDestroy() {
new MainView(this).stopPlay();
super.onDestroy();
}
}
mainifest文件app
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test.xingliu.texturesample">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
效果图以下,因为资源是网络上的,须要联网才能播放ide
须要注意到是在硬件加速的状况下,TextureView是用GPU渲染的,软件上的Canvas是不能进行处理的,而TextureView必须在硬件加速的窗口中,能够调用lockcanvas()方法来获取canvas动画