Android截屏SurfaceView黑屏問題的解決辦法
最近項目中有截屏的需求,普通的view截屏方法網(wǎng)上一搜一大把,但是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方法中創(chuàng)建了一塊畫布,進行SurfaceView的繪制,但是我們知道SurfaceView是雙緩沖機制,這個Canvas上的內(nèi)容我們拿不到,所以截屏出來是黑屏。所以,要拿到這個畫布上的內(nèi)容,就自己創(chuàng)建一個畫布,將這些內(nèi)容畫到自己的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);//解鎖畫布,提交畫好的圖像 } } //將繪制圖案的方法抽象出來,讓子類實現(xiàn),調(diào)用getBitmap方法時就會調(diào)用此方法 protected abstract void doDraw(Canvas canvas); //調(diào)用該方法將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) { //調(diào)用該方法即可得到surfaceview上繪制的圖案 Bitmap bitmap = surfaceView.getBitmap(); } });
補充:如果界面上還有其他控件需要一起截屏,可以將截到的surfaceview的bitmap和用普通辦法截到的不含surfaceview的bitmap拼接起來就OK了,至于兩個bitmap合為一個bitmap的方法,百度一下有很多,不再贅述。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android中Java instanceof關(guān)鍵字全面解析
instanceof關(guān)鍵字用于判斷一個引用類型變量所指向的對象是否是一個類(或接口、抽象類、父類)的實例.這篇文章主要介紹了Android中Java instanceof關(guān)鍵字全面解析的相關(guān)資料,需要的朋友可以參考下2016-07-07Android?常見獲取設(shè)備標識方法總結(jié)
隨著Android系統(tǒng)版本更新,Google對用戶隱私保護增強,限制獲取設(shè)備標識,文中測試DeviceID、ANDROID_ID、Serial、MAC地址等方法在不同API級別的表現(xiàn),感興趣的朋友跟隨小編一起看看吧2024-09-09RecyclerView中監(jiān)聽EditText變化的BUG的解決方法
本篇文章主要介紹了RecyclerView中監(jiān)聽EditText變化的BUG的解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11官網(wǎng)項目Jetpack?Startup庫學(xué)習(xí)
這篇文章主要為大家介紹了官網(wǎng)項目Jetpack?Startup庫學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02android中SwipeRefresh實現(xiàn)各種上拉,下拉刷新示例
這篇文章主要介紹了android中SwipeRefresh實現(xiàn)各種上拉,下拉刷新示例,非常具有實用價值,需要的朋友可以參考下。2017-03-03Android實現(xiàn)旋轉(zhuǎn)動畫的兩種方式案例詳解
這篇文章主要介紹了Android實現(xiàn)旋轉(zhuǎn)動畫的兩種方式,需要的朋友可以參考下2021-08-08android TextView 設(shè)置和取消刪除線的兩種方法
這篇文章主要介紹了android TextView 設(shè)置和取消刪除線的兩種方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03