SurfaceView控件:
* 1.主要用来显示图像数据,直接能从硬件接口里面获取数据: 视屏播放,拍照,二维码扫描或者游戏背景。。。
* 2.该控件具有双缓冲机制,实现效率高
* 3.能够在子线程中修改UI
* 4.SurfaceView控件的绘制内容,是靠内部类SurfaceHolder来进行绘制的
制作视频播放(本地视频和有URL类的视频)
* 1.主要用来显示图像数据,直接能从硬件接口里面获取数据: 视屏播放,拍照,二维码扫描或者游戏背景。。。
* 2.该控件具有双缓冲机制,实现效率高
* 3.能够在子线程中修改UI
* 4.SurfaceView控件的绘制内容,是靠内部类SurfaceHolder来进行绘制的
使用步骤:
* 1.继承surfaceview控件,同时去实现surfaceholder.callback接口
* 2.得到里面的surfaceholder
* 3.surfaceholder去实现addcallback(3个回调方法,管surfaceview显示的生命周期)
* 4.通过surfaceholder拿到画布canvas
* 5.绘图
* 6.通过surfaceholder提交绘制内容
自定义一个矩形
自定义一个类
//1.创建MySurfaceView
class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{
//拿到surfaceholder内部的holder,这个是控制绘制内容
private SurfaceHolder holder;
//绘制图像的画笔
private Paint paint;
public MySurfaceView(Context context) {
super(context);
init();
}
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
//2.拿到holder
holder=getHolder();
//3.
holder.addCallback(this);
paint=new Paint();
paint.setColor(Color.RED);
}
//控制显示界面的生命周期
@Override
public void surfaceCreated(SurfaceHolder holder) {
//4.holder通过调用方法难道绘图的画布
Canvas canvas = holder.lockCanvas();
//5.进行内容绘制,开个线程
canvas.drawRect(20,20,120,120,paint);
//6.绘制完成之后进行提交内容
holder.unlockCanvasAndPost(canvas);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
自定义一个倒计时
public class MyTwoSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
//2.
private SurfaceHolder holder;
//绘制矩形的设置
private Paint paint, txtPaint;
//显示文字倒计时
private int count = 60;
//控制线程
private boolean flag=true;
public MyTwoSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyTwoSurfaceView(Context context) {
super(context);
init();
}
private void init() {
holder = getHolder();
//3.
holder.addCallback(this);
paint = new Paint();
paint.setColor(Color.YELLOW);
//绘制文字的大小和文字宽度
txtPaint = new Paint();
txtPaint.setStrokeWidth(10);
txtPaint.setTextSize(20);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
//开启线程执行绘制
new MyDrawThread(holder).start();
flag=true;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
flag=false;
}
//开启一个线程绘制显示的内容
//倒计时60-0
class MyDrawThread extends Thread {
//拿到surfaceview里面的holder
SurfaceHolder holder;
public MyDrawThread(SurfaceHolder holder) {
this.holder = holder;
}
@Override
public void run() {
super.run();
Canvas canvas;
while (flag) {
canvas = holder.lockCanvas();
//绘制矩形
canvas.drawRect(20, 20, 120, 120, paint);
//绘制倒计时文字部分
if (count == 0) {
count=60;
canvas.drawText("倒计时开始" + count--, 30, 60, txtPaint);
} else {
canvas.drawText("倒计时" + count--, 30, 60, txtPaint);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
holder.unlockCanvasAndPost(canvas);
}
}
}
}
制作视频播放(本地视频和有URL类的视频)
布局文件这些都可以直接拿过用
<SurfaceView
android:id="@+id/surfaceview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="8"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="20dp">
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<Button
android:id="@+id/bt_play"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:onClick="onclick"
android:text="播放"/>
<Button
android:id="@+id/bt_pouse"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:onClick="onclick"
android:text="暂停"/>
<Button
android:id="@+id/bt_stop"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:onClick="onclick"
android:text="停止"/>
</LinearLayout>
activity里面的代码:
/**
* Surfaceview结合MediaPlayer做视屏播放
* mp4.3gp.
*/
public class MainActivity extends AppCompatActivity {
//视屏播放显示界面
private SurfaceView surfaceview;
private SurfaceHolder holder;
//控制播放进度
private SeekBar seekbar;
//音频播放器
private MediaPlayer mediaPlayer;
//计时器对象
private Timer timer=new Timer();
private TimerTask task;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==0){
//更新进度条
seekbar.setProgress(mediaPlayer.getCurrentPosition());
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
setProgressSeekBar();
}
private void setProgressSeekBar() {
task=new TimerTask() {
@Override
public void run() {
//更新操作
handler.sendEmptyMessage(0);
}
};
timer.schedule(task,0,10);
}
private void init() {
surfaceview = (SurfaceView) findViewById(R.id.surfaceview);
holder=surfaceview.getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
mediaPlayer=new MediaPlayer();
seekbar = (SeekBar) findViewById(R.id.seekbar);
//拉动seekbar的时候更改播放进度
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//设置播放进度
mediaPlayer.seekTo(seekBar.getProgress());
}
});
//seekbar.setProgress(mediaPlayer.getCurrentPosition());
}
public void onclick(View view) {
switch (view.getId()) {
case R.id.bt_play:
playMedia();
break;
case R.id.bt_pouse:
if(mediaPlayer.isPlaying()){
mediaPlayer.pause();
}else {
mediaPlayer.start();
}
break;
case R.id.bt_stop:
mediaPlayer.stop();
break;
}
}
//播放视屏
private void playMedia() {
mediaPlayer.reset();//停止之后在开启播放
//设置播放视频的路径
String path= Environment.getExternalStorageDirectory()+ File.separator+"movie.mp4";
File file=new File(path);
if(file.exists()) {
try {
//设置视屏播放的路径,可以是一个mp4的视屏网址,mp4,3gp,
mediaPlayer.setDataSource(file.getAbsolutePath());
//设置视屏播放界面holder
mediaPlayer.setDisplay(holder);
//设置视屏准备
mediaPlayer.prepareAsync();
//设置是否准备好的监听
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if(mp.getVideoHeight()>0&&mp.getVideoWidth()>0){
//视屏播放方法
mp.start();
//设置播放进度条最大长度
seekbar.setMax(mp.getDuration());
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
}else{
Toast.makeText(this,"null",Toast.LENGTH_SHORT).show();
}
}
}