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();
- }
- }