先写在了我的QQ空间上....现在开了博客转过来
理解有错误的地方欢迎指正!
Textureview是google在android4.0后推出的一个新的控件,网上关于这方面的资料几乎没有,差不多全是官网的一些DEMO,花了一天时间研究了一下,基本上对于这一控件有了些认识。
官方的解释:
Textureview可以用来显示内容流。这样一个内容流例如可以视频或者OpenGL的场景。内容流可以来自本应用程序以及其他程序。
google在以前的相机预览是一直使用surfaceview来实现的, 但是现在 Textureview已经代替了surfaceveiw来实现这一效果,不过 Textureview真正厉害的地方在于它拥有普通view 的一切特性,surfaceview使用了双缓冲技术,所以想要运用一些动画效果时经常出现莫名其妙的错误,但 Textureview完全不存在这一问题。Textureview还能渲染来自OpenGL的内容,我感觉这是google用来平衡GLsurfaceview的一种想法,以前的GLsurfaceview作为曾经OpenGL ES唯一使用的地方,有很大的局限性,但Textureview打破了这一情况,它可以随时随地的用来显示OpenGL流的内容。
关于Textureview在相机方面的运用,官网已经有了DEMO,就不重复再造车轮了,以下是关于Textureview在视频方面的一些运用方法。
最简单的用法,在一个界面下同时开启4个视频流播放(怕开太多卡,所以只开了4个,理论上想开多少开多少,实测同时开4 个中下性能的机子还是很流畅的),左上角的Textureview用添加了点击动画,点击后可以绕Y轴旋转
掌握了简单的用法,高级点的用法就容易多了,可以根据自己的创意来整,比如可以嵌入到一个列表中,或者视频播放的3D切换等很酷的效果。
主Activity就比较简单了,代码如下:
最后效果如下:
![微笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/smile.gif)
Textureview是google在android4.0后推出的一个新的控件,网上关于这方面的资料几乎没有,差不多全是官网的一些DEMO,花了一天时间研究了一下,基本上对于这一控件有了些认识。
官方的解释:
Textureview可以用来显示内容流。这样一个内容流例如可以视频或者OpenGL的场景。内容流可以来自本应用程序以及其他程序。
google在以前的相机预览是一直使用surfaceview来实现的, 但是现在 Textureview已经代替了surfaceveiw来实现这一效果,不过 Textureview真正厉害的地方在于它拥有普通view 的一切特性,surfaceview使用了双缓冲技术,所以想要运用一些动画效果时经常出现莫名其妙的错误,但 Textureview完全不存在这一问题。Textureview还能渲染来自OpenGL的内容,我感觉这是google用来平衡GLsurfaceview的一种想法,以前的GLsurfaceview作为曾经OpenGL ES唯一使用的地方,有很大的局限性,但Textureview打破了这一情况,它可以随时随地的用来显示OpenGL流的内容。
关于Textureview在相机方面的运用,官网已经有了DEMO,就不重复再造车轮了,以下是关于Textureview在视频方面的一些运用方法。
最简单的用法,在一个界面下同时开启4个视频流播放(怕开太多卡,所以只开了4个,理论上想开多少开多少,实测同时开4 个中下性能的机子还是很流畅的),左上角的Textureview用添加了点击动画,点击后可以绕Y轴旋转
掌握了简单的用法,高级点的用法就容易多了,可以根据自己的创意来整,比如可以嵌入到一个列表中,或者视频播放的3D切换等很酷的效果。
动画效果使用了NineOldAndroid 开源动画库,地址http://nineoldandroids.com/
代码方面:
布局文件默认一个relativelayout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent"
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" >
</RelativeLayout>
然后自己实现一个 自定义Textureview,创建默认的构造函数,最重要的是在内部实现一个TextureView.SurfaceTextureListener,实现对Textureview的监听,主要的处理逻辑全部在SurfaceTextureListener的重载方法中实现
public class mtextureview extends TextureView {
MediaPlayer mp;
Context context;
Surface s;
Uri uri;
public mtextureview(Context context) {//构造函数
super(context);
this.context = context;
this.setSurfaceTextureListener(new listener());
mp=MediaPlayer.create(context, R.raw.test1);
Log.d("HOME", "oncreat");
}
public void setUri(Uri uri) {
this.uri = uri;
}
public class listener implements TextureView.SurfaceTextureListener{
@Override
public void onSurfaceTextureAvailable(SurfaceTexture arg0, int arg1,
int arg2) {
// TODO 自动生成的方法存根
Log.d("YES", "HERE");
s=new Surface(arg0);
try {
if(mp!=null)
{
mp.stop();
}
mp.setSurface(s);
mp.prepare();
mp.start();
} catch (Exception e) {
// TODO: handle exception
}
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture arg0) {
// TODO 自动生成的方法存根
mp.release();
return true;
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture arg0, int arg1,
int arg2) {
// TODO 自动生成的方法存根
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture arg0) {
// TODO 自动生成的方法存根
}
}
}
主Activity就比较简单了,代码如下:
public class MainActivity extends Activity {
RelativeLayout parent;
RelativeLayout.LayoutParams params1, params2, params3, params4;
mtextureview video1, video2, video3, video4;
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getBaseContext();
initview();
}
@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;
}
public void initview() {
parent = (RelativeLayout) findViewById(R.id.parent);
params1 = new RelativeLayout.LayoutParams(450, 450);
params1.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
params2 = new RelativeLayout.LayoutParams(450, 450);
params2.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
params2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
params3 = new RelativeLayout.LayoutParams(450, 450);
params3.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
params3.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
params4 = new RelativeLayout.LayoutParams(450, 450);
params4.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
params4.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
video1 = new mtextureview(context);
video2 = new mtextureview(context);
video3 = new mtextureview(context);
video4 = new mtextureview(context);
video1.setLayoutParams(params1);
video2.setLayoutParams(params2);
video3.setLayoutParams(params3);
video4.setLayoutParams(params4);
parent.addView(video1);
parent.addView(video2);
parent.addView(video3);
parent.addView(video4);
video1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO 自动生成的方法存根
ObjectAnimator.ofFloat(video1, "rotationY", 0, 180, 0)
.setDuration(3000).start();
}
});
}
}