Android TextureView简易教程

泡在网上的日子 / 文 发表于2014-12-13 13:51 次阅读 TextureView

如果你想显示一段在线视频或者任意的数据流比如视频或者OpenGL 场景,你可以用android中的TextureView做到。

TextureView的兄弟SurfaceView

应用程序的视频或者opengl内容往往是显示在一个特别的UI控件中:SurfaceView。SurfaceView的工作方式是创建一个置于应用窗口之后的新窗口。这种方式的效率非常高,因为SurfaceView窗口刷新的时候不需要重绘应用程序的窗口(android普通窗口的视图绘制机制是一层一层的,任何一个子元素或者是局部的刷新都会导致整个视图结构全部重绘一次,因此效率非常低下,不过满足普通应用界面的需求还是绰绰有余),但是SurfaceView也有一些非常不便的限制。

因为SurfaceView的内容不在应用窗口上,所以不能使用变换(平移、缩放、旋转等)。也难以放在ListView或者ScrollView中,不能使用UI控件的一些特性比如View.setAlpha()

为了解决这个问题 Android 4.0中引入了TextureView。

TextureView

与SurfaceView相比,TextureView并没有创建一个单独的Surface用来绘制,这使得它可以像一般的View一样执行一些变换操作,设置透明度等。另外,Textureview必须在硬件加速开启的窗口中。

TextureView的使用非常简单,你唯一要做的就是获取用于渲染内容的SurfaceTexture。具体做法是先创建TextureView对象,然后实现SurfaceTextureListener接口,代码如下:

private TextureView myTexture;
public class MainActivity extends Activity implements SurfaceTextureListener{
protected void onCreate(Bundle savedInstanceState) {
   myTexture = new TextureView(this);
   myTexture.setSurfaceTextureListener(this);
   setContentView(myTexture);
   }
}

Activity implementsSurfaceTextureListener接口因此activity中需要重写如下方法:

@Override
public void onSurfaceTextureAvailable(SurfaceTexture arg0, int arg1, int arg2) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture arg0) {
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture arg0, int arg1,int arg2) {
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture arg0) {
}


TextureView可以使用setAlphasetRotation方法达到改变透明度和旋转的效果。

myTexture.setAlpha(1.0f);
myTexture.setRotation(90.0f);

除了上面的方法之外,TextureView 还有如下方法:

序号方法&描述
1getSurfaceTexture()
This method returns the SurfaceTexture used by this view.
2getBitmap(int width, int height)
This method returns Returns a Bitmap representation of the content of the associated surface texture.
3getTransform(Matrix transform)
This method returns the transform associated with this texture view.
4isOpaque()
This method indicates whether this View is opaque.
5lockCanvas()
This method start editing the pixels in the surface
6setOpaque(boolean opaque)
This method indicates whether the content of this TextureView is opaque.
7setTransform(Matrix transform)
This method sets the transform to associate with this texture view.
8unlockCanvasAndPost(Canvas canvas)
This method finish editing pixels in the surface.

例子

下面的例子演示了如何使用TextureView类,我们创建了一个可以在TextureView中预览Camera的demo,可以改变它的角度以及方向。当然程序需要运行在有摄像头的设备上。

下面是MainActivity.java中的代码:

package com.example.textureview;
import java.io.IOException;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Menu;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
import android.view.View;
import android.widget.FrameLayout;
public class MainActivity extends Activity implements SurfaceTextureListener {
   private TextureView myTexture;
   private Camera mCamera;
   @SuppressLint("NewApi")
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      myTexture = new TextureView(this);
      myTexture.setSurfaceTextureListener(this);
      setContentView(myTexture);
   }
   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.main, menu);
      return true;
   }
   @SuppressLint("NewApi")
   @Override
   public void onSurfaceTextureAvailable(SurfaceTexture arg0, int arg1,
   int arg2) {
      mCamera = Camera.open();
      Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
      myTexture.setLayoutParams(new FrameLayout.LayoutParams(
      previewSize.width, previewSize.height, Gravity.CENTER));
      try {
         mCamera.setPreviewTexture(arg0);
        } catch (IOException t) {
        }
      mCamera.startPreview();
      myTexture.setAlpha(1.0f);
      myTexture.setRotation(90.0f);
   }
   @Override
   public boolean onSurfaceTextureDestroyed(SurfaceTexture arg0) {
      mCamera.stopPreview();
      mCamera.release();
      return true;
   }
   @Override
   public void onSurfaceTextureSizeChanged(SurfaceTexture arg0, int arg1,
   int arg2) {
   // TODO Auto-generated method stub
   }
   @Override
   public void onSurfaceTextureUpdated(SurfaceTexture arg0) {
   // TODO Auto-generated method stub
   }
}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context=".MainActivity" >
   <TextureView
      android:id="@+id/textureView1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true" />
</RelativeLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.textureview"
   android:versionCode="1"
   android:versionName="1.0" >
   <uses-sdk
      android:minSdkVersion="8"
      android:targetSdkVersion="17" />
   <uses-permission android:name="android.permission.CAMERA"/>
   <application
      android:allowBackup="true"
      android:icon="@drawable/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppTheme" >
      <activity
         android:name="com.example.textureview.MainActivity"
         android:label="@string/app_name" >
         <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
       </activity>
   </application>
</manifest>


不同参数下的截图:

myTexture.setAlpha(0.5f);

myTexture.setRotation(45.0f);

Anroid TextureView Tutorial

myTexture.setAlpha(1.5f);

myTexture.setRotation(45.0f);

Anroid TextureView Tutorial

myTexture.setAlpha(1.0f);

myTexture.setRotation(90.0f);

Anroid TextureView Tutorial

收藏 赞 (40) 踩 (0)
上一篇:android手势处理揭秘
当滑动(fling)比移动(scroll)有更高的效率时,为什么要让用户使用scroll操作呢?在面积很小而数据又很多的移动设备上,要显示远在后面的那些内容scroll是很困难的,这种情况下fling更适合。 注:scroll表示手指滑动多少距离,界面跟着显示多少距离,而fl
下一篇:基于textureview编写opengl程序
ps这篇文章不仅可以更清楚的了解TextureView,还可以学到一点关于opengl的知识。 与SurfaceView相比,TextureView并没有创建一个单独的Surface用来绘制,这使得它可以像一般的View一样执行一些变换操作,设置透明度等。 另外,Textureview必须在硬件加速开启