Android截屏SurfaceView黑屏问题的解决办法

 更新时间:2021年07月11日 09:46:02   作者:风二中  
这篇文章主要为大家详细介绍了Android截屏SurfaceView黑屏问题的解决办法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

最近项目中有截屏的需求,普通的view截屏方法网上一搜一大把,但是SurfaceView截屏黑屏问题很多文章说的并不清楚,自己参考了一些别的博客,再加上自己的思考,算是找到了一种解决方案。

1、首先看我们一般是怎么用SurfaceView的

public class SuperSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
 SurfaceHolder surfaceHolder;
 
 public SuperSurfaceView(Context context) {
  super(context);
  surfaceHolder = this.getHolder();
  surfaceHolder.addCallback(this);
 }
 
 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
 
 }
 
 @Override
 public void surfaceCreated(SurfaceHolder holder) {
  new Thread(new MyThread()).start();
 }
 
 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {
 
 }
 
 class MyThread implements Runnable {
  @Override
  public void run() {
   Canvas canvas = surfaceHolder.lockCanvas(null);//获取画布
   Paint mPaint = new Paint();
   mPaint.setColor(Color.BLUE);
   canvas.drawRect(new RectF(100, 100, 1000, 550), mPaint);
   surfaceHolder.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像
 
  }
 }
}

从以上代码中,可以看到在MyThread的run方法中创建了一块画布,进行SurfaceView的绘制,但是我们知道SurfaceView是双缓冲机制,这个Canvas上的内容我们拿不到,所以截屏出来是黑屏。所以,要拿到这个画布上的内容,就自己创建一个画布,将这些内容画到自己的Canvas上,就可以了。

2、拿到SurfaceView画布上的bitmap,看修改过后的代码

public abstract class SuperSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
 SurfaceHolder surfaceHolder;
 
 public SuperSurfaceView(Context context) {
  super(context);
  surfaceHolder = this.getHolder();
  surfaceHolder.addCallback(this);
 }
 
 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
 
 }
 
 @Override
 public void surfaceCreated(SurfaceHolder holder) {
  new Thread(new MyThread()).start();
 }
 
 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {
 
 }
 
 class MyThread implements Runnable {
  @Override
  public void run() {
   Canvas canvas = surfaceHolder.lockCanvas(null);//获取画布
   doDraw(canvas);
   surfaceHolder.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像
 
  }
 }
 
 //将绘制图案的方法抽象出来,让子类实现,调用getBitmap方法时就会调用此方法
 protected abstract void doDraw(Canvas canvas);
 
 //调用该方法将doDraw绘制的图案绘制在自己的canvas上
 public Bitmap getBitmap() {
  Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
  Canvas canvas = new Canvas(bitmap);
  doDraw(canvas);
  return bitmap;
 }
}

3、下面看MainActivity中如何使用

Button bt = (Button) findViewById(R.id.bt);
FrameLayout fl = (FrameLayout) findViewById(R.id.fl);
//用到surfaceview需继承SuperSurfaceView才能截到屏,否则截出来是黑屏
SuperSurfaceView surfaceView = new SuperSurfaceView(this) {
 @Override
 protected void doDraw(Canvas canvas) {
  Paint mPaint = new Paint();
  mPaint.setColor(Color.BLUE);
  canvas.drawRect(new RectF(100, 100, 1000, 550), mPaint);
 }
};
fl.addView(surfaceView);
 
bt.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
  //调用该方法即可得到surfaceview上绘制的图案
  Bitmap bitmap = surfaceView.getBitmap();
 }
});

补充:如果界面上还有其他控件需要一起截屏,可以将截到的surfaceview的bitmap和用普通办法截到的不含surfaceview的bitmap拼接起来就OK了,至于两个bitmap合为一个bitmap的方法,百度一下有很多,不再赘述。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 详解Android 8.0以上系统应用如何保活

    详解Android 8.0以上系统应用如何保活

    这篇文章主要介绍了详解Android 8.0以上系统应用如何保活,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Android 进度条按钮ProgressButton的实现代码

    Android 进度条按钮ProgressButton的实现代码

    这篇文章主要介绍了Android 进度条按钮实现(ProgressButton)代码,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2018-10-10
  • Android开发之BroadcastReceiver用法实例分析

    Android开发之BroadcastReceiver用法实例分析

    这篇文章主要介绍了Android开发之BroadcastReceiver用法,实例分析了Android中广播的相关使用技巧,需要的朋友可以参考下
    2015-05-05
  • Android 进度条显示在标题栏的实现方法

    Android 进度条显示在标题栏的实现方法

    android进度条显示在标题栏的实现方法,大概分文xml文件和java文件,具体代码内容大家可以通过本文学习下
    2017-01-01
  • Android小工具自定义view课表

    Android小工具自定义view课表

    这篇文章主要为大家详细介绍了Android小工具自定义view课表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-09-09
  • VideoView实现视频无缝连续播放

    VideoView实现视频无缝连续播放

    这篇文章主要为大家详细介绍了VideoView实现视频无缝连续播放,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • Android事件分发机制 ViewGroup分析

    Android事件分发机制 ViewGroup分析

    这篇文章主要介绍了Android事件分发机制 ViewGroup分析,事件分发从手指触摸屏幕开始,即产生了触摸信息,被底层系统捕获后会传递给Android的输入系统服务IMS,更多相关介绍,需要的朋友可以参考一下
    2022-09-09
  • Android显示富文本+夜间深色模式

    Android显示富文本+夜间深色模式

    大家好,本篇文章主要讲的是Android显示富文本+夜间深色模式,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2022-01-01
  • Android实现自定义标题栏的方法

    Android实现自定义标题栏的方法

    这篇文章主要介绍了Android实现自定义标题栏的方法,需要的朋友可以参考下
    2015-12-12
  • Android底部导航栏的动态替换方案

    Android底部导航栏的动态替换方案

    这篇文章主要为大家详细介绍了Android底部导航栏的动态替换方案,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12

最新评论