自學了android有幾個月了,跟著網(wǎng)上的節(jié)奏,應(yīng)該早點寫些博客來提高自己的水準的。但苦于技術(shù)水準始終不自信(也是不過關(guān)的結(jié)果吧),就一直只是將自己學習過程中的問題和重要的知識點寫在自己的筆記文檔中。
創(chuàng)新互聯(lián)總部坐落于成都市區(qū),致力網(wǎng)站建設(shè)服務(wù)有成都做網(wǎng)站、網(wǎng)站制作、網(wǎng)絡(luò)營銷策劃、網(wǎng)頁設(shè)計、網(wǎng)站維護、公眾號搭建、微信小程序定制開發(fā)、軟件開發(fā)等為企業(yè)提供一整套的信息化建設(shè)解決方案。創(chuàng)造真正意義上的網(wǎng)站建設(shè),為互聯(lián)網(wǎng)品牌在互動行銷領(lǐng)域創(chuàng)造價值而不懈努力!
但,總感覺一個人寫下來成就感還是欠缺了那么一些,而且有些問題及解答方法拋出來,是有可能得到更多好的反饋及解決方案的。于是,本著不作不會死的心態(tài),一步一步在技術(shù)成長的道路前行——>這篇博客就是其中一步!
若博客中有些技術(shù)知識點有誤或者有更優(yōu)化的解答方案,還望各位小伙伴多多指出。
以下是正題了:
目標:利用SurfaceView實現(xiàn)一個簡單的計時器
圖示:
描述:1.利用SurfaceView來實現(xiàn)計時功能,同時不斷將圓弧畫滿;2.點擊按鈕可以停止計時;
重點:
1.自定義SurfaceView中針對SurfaceHolder.CallBack的三個方法進行覆寫;
2.通過surfaceHolder.lockCanvas()在新開的線程中得到canvas對象,從而進行圖形和時間文字的繪制;
3.通過設(shè)置flag值,從而控制在線程run()方法中邏輯代碼的執(zhí)行;
重要部分代碼:
public TestView(Context context) { super(context); surfaceHolder = getHolder(); surfaceHolder.addCallback(this); countThread = new CountThread(surfaceHolder); } public TestView(Context context, AttributeSet attributeSet) { super(context, attributeSet); surfaceHolder = getHolder(); surfaceHolder.addCallback(this); countThread = new CountThread(surfaceHolder); }
以上為自定義的SurfaceView(TestView)的構(gòu)造函數(shù),做相應(yīng)的初始化工作。(第二個構(gòu)造方法在實現(xiàn)過程中沒有覆寫,導(dǎo)致如果是通過布局文件引入進Activity中時,則顯示不出View——>也就是一般自定義View一定要覆寫的構(gòu)造方法)。
在構(gòu)造方法中初始化了自定義的內(nèi)部線程類CountThread,用來執(zhí)行繪制工作。
以下為CountThread類的run()方法執(zhí)行邏輯:
@Override public void run() { Canvas canvas = null; int pivotX = getResources().getDisplayMetrics().widthPixels / 2; RectF rectF = new RectF(pivotX - 300, pivotX - 300, pivotX + 300, pivotX + 300); while (!isStop) { try { canvas = surfaceHolder.lockCanvas(); canvas.drawColor(Color.WHITE);//設(shè)置畫布背景為白色 // canvas.drawRoundRect(300, 300, 600, 600, 150, 150, paint);//直接使用該行代碼來畫圓是行不通的,因為這個方法要求版本21,我的手機運行android版本是19 canvas.drawArc(rectF, -90, endAngle++, false, paint);//-90在這里不等于270,所以要想從最上方開始畫弧,就得用-90 canvas.drawText(countTime(endAngle), pivotX, pivotX, paintText);//顯示計算的時間 Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } finally { if (canvas != null) {//需要對canvas進行非空判斷 surfaceHolder.unlockCanvasAndPost(canvas); } } } }
主要就是通過Thread.sleep(1000)來停頓一秒,從而通過endAngle來計數(shù)。
至此,基本的程序邏輯已經(jīng)實現(xiàn)。再講該自定義View引入進Activity指定的layout布局文件中即可進行顯示。
但,這其中也會涉及到相應(yīng)的問題。譬如:
1.圖示中的按鈕無法顯示出來,只能看到自定義的SurfaceView的視圖;
我的做法是:將布局設(shè)定為FrameLayout即可。因為SurfaceView是浮在窗口的一層,那么就可以把它看做一個圖層。
2.java.lang.IllegalThreadStateException:Thread already started
該錯誤表明,線程已經(jīng)存在了。這種錯誤的操作重現(xiàn)是:按下home鍵或者menu鍵會導(dǎo)致該自定的SurfaceView銷毀,但線程并沒有被銷毀,再次啟動該自定義SurfaceView的時候又去重新啟動該線程。解決的方法是:
@Override public void surfaceCreated(SurfaceHolder holder) { if (!countThread.isAlive()) {//如果線程不存在,則啟動線程——>當應(yīng)用掛起的時候Thread是存在的,如果不做這個判斷,會報“Thread already started ”錯誤 countThread.start();//SurfaceView創(chuàng)建時開啟線程 } }
在surfaceCreated()方法中對該線程是否是在存活中進行判斷。
當然,這里面還有最重要的一個問題:
當按下home鍵或者menu鍵時,程序是沒有在計時的。那么這種情況下,我的一個解決方案是,通過開啟一個service來接收程序停止( onStop() )時已經(jīng)計時的數(shù)值,然后傳遞給service記下并計時,當應(yīng)用程序界面重新回歸屏幕時( onRestart() )則將數(shù)據(jù)取出并回傳到自定義的SurfaceView的邏輯run()方法中繼續(xù)計時。
整個小程序的代碼可以通過以下鏈接下載:
點擊進入下載頁面:http://xiazai.jb51.net/201701/yuanma/AndroidSurfaceView(jb51.net).rar
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
分享名稱:Android利用SurfaceView實現(xiàn)簡單計時器
文章轉(zhuǎn)載:http://www.rwnh.cn/article26/jeedjg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、網(wǎng)站維護、電子商務(wù)、ChatGPT、網(wǎng)站導(dǎo)航、域名注冊
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)