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