Android自定義有限制區(qū)域圖例角度自識別涂鴉工具類
自定義View分為繼承自View和ViewGroup,繼承ViewGroup相比繼承View
- 在事件分發(fā)上ViewGroup多dispatchTouchEvent(事件分發(fā))和onInterceptTouchEvent(事件攔截)兩個方法
- 在繼承上ViewGroup需要著重處理onmeasure(測量)與onLayout(控制位置等),而繼承View重點在于onDrow(繪制)上
這篇我們就簡單實現(xiàn)一個自定義簽名類,通過手指觸摸屏幕移動,顯示手指滑過的路徑。首先創(chuàng)建SignatureView并繼承自View:
class SignatureView constructor(context: Context?, attrs: AttributeSet? = null) : View(context, attrs, 0) { private lateinit var paint: Paint private var mWidth = 0 //父類寬度 private var mHeight = 0//父類高度 override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { super.onMeasure(widthMeasureSpec, heightMeasureSpec) mWidth = MeasureSpec.getSize(widthMeasureSpec) mHeight = MeasureSpec.getSize(heightMeasureSpec) paint = Paint() //設(shè)置抗鋸齒 paint.isAntiAlias = true //設(shè)置簽名筆畫樣式 paint.style = Paint.Style.STROKE setMeasuredDimension(mWidth, mHeight) } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) ...... } }
接下來需要做的其實就只有觸摸事件處理和繪制路徑兩個任務(wù)了。繪制需要在onDraw中通過咱們初始化的畫筆paint和canvas完成,那么觸摸事件則需要重寫onTouchEvent方法監(jiān)聽:
override fun onTouchEvent(event: MotionEvent): Boolean { super.onTouchEvent(event) }
這里需要注意,由于簽名是實時記錄的,所以我們需要記錄下滑動的點,將其連接成一條線,再通過pain畫線。畫的過程是按下移動的操作,所以在ACTION_MOVE的過程我們需要實時畫線。畫筆完成是抬起的動作,所以在ACTION_UP時我們需要將之前的所有點繪制在畫布上。這里通過一個點的集合收集手指移動的點,用戶畫筆繪制。
//收集用戶繪制的點 private var allPoints: MutableList<Point> = ArrayList() val p = Point(event.x.toInt(), event.y.toInt()) when (event.action) { MotionEvent.ACTION_DOWN -> { //用戶按下,表示重新開始保存點 allPoints.clear() allPoints.add(p) } MotionEvent.ACTION_UP -> { postInvalidate() //重繪圖像 } MotionEvent.ACTION_MOVE -> { allPoints.add(p) postInvalidate() //子線程可刷新 } }
接下來就是在onDrow()中繪制,通過canvas.drawLine:
val first = allPoints[0] //第一個點 val last = allPoints[allPoints.size-1] //最后一個點 canvas.drawLine(first.x.toFloat(),first.y.toFloat(),last.x.toFloat(),last.y.toFloat(),paint)
到這里基本就結(jié)束了,但我們還需要撤回和清除的功能。這時候就需要想一想了,如果按照按下—>移動—>抬起為一筆,那么撤回的話就需要將這個過程的所有點都清除。此時我們就可以將這個過程想象成一條線,在按下時記錄線的開始,抬起記錄線的結(jié)束,再將這條線存放在一個集合中,如果需要撤回就將這條數(shù)據(jù)刪除。
//用于畫完圖后的顯示,在抬起時,添加來自于allPoints的所有點的數(shù)據(jù) private var allList: MutableList<List<Point>> = ArrayList() //用于劃線過程中的顯示,當集合allList存儲后,清空本集合中所有數(shù)據(jù) private var allPoints: MutableList<Point> = ArrayList() override fun onTouchEvent(event: MotionEvent): Boolean { super.onTouchEvent(event) val p = Point(event.x.toInt(), event.y.toInt()) when (event.action) { MotionEvent.ACTION_DOWN -> { //用戶按下,表示重新開始保存點 allPoints = ArrayList() allPoints.add(p) } MotionEvent.ACTION_UP -> { //用戶松開 allList.add(allPoints) allPoints = ArrayList() //添加集合后,清除子集合 postInvalidate() //重繪圖像 } MotionEvent.ACTION_MOVE -> { allPoints.add(p) postInvalidate() //子線程可刷新 } } return true } //上一步(清除本次繪畫) fun clearLatestData() { if (allList.size > 0) { allList.removeAt(allList.size - 1) paints.removeAt(paints.size - 1) } postInvalidate() }
清除就更簡單了,直接清空集合中的所有線條即可,但一定不要忘記刷新視圖:
//重置(清除所有繪畫) fun clearAllData() { allList.clear() postInvalidate() }
總結(jié)
其實整套下來說難也不難,主要涉及的就是繼承自View方式的自定義View。由易而難,先實現(xiàn)最基礎(chǔ)的功能,通過觸摸事件的不同動作采集我們需要的數(shù)據(jù),再配合onDrow方法繪制出采集的線條,一定不要忘記刷新視圖。撤回或者說多顏色,多樣式的線條其實都是可以通過容器收集線條,針對不同的線條設(shè)置畫筆(paint)屬性達到需求的。這篇就講到這里希望對大家有所幫助,下篇咱們講講異形區(qū)域限制畫筆區(qū)域問題。
以上就是Android自定義有限制區(qū)域圖例角度自識別涂鴉工具類的詳細內(nèi)容,更多關(guān)于Android限制區(qū)域涂鴉工具類的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android中實現(xiàn)開機自動啟動服務(wù)(service)實例
這篇文章主要介紹了Android中實現(xiàn)自動啟動服務(wù)實例,并開機自動啟用(無activity),的朋友可以參考下2014-06-06Android Studio 新手入門教程(一)基本設(shè)置圖解
這篇文章主要介紹了Android Studio 新手入門教程(一)基本設(shè)置圖解,需要的朋友可以參考下2017-12-12Android編程實現(xiàn)動態(tài)支持多語言的方法
這篇文章主要介紹了Android編程實現(xiàn)動態(tài)支持多語言的方法,涉及Android資源、控件及屬性相關(guān)操作技巧,需要的朋友可以參考下2017-06-06Android FlowLayout流式布局實現(xiàn)詳解
這篇文章主要為大家詳細介紹了Android FlowLayout流式布局的實現(xiàn)方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-09-09Android自定義View實現(xiàn)體重表盤詳解流程
對于安卓程序員來說,自定義view簡直不要太重要,畢竟有很多功能,譬如圓形頭像這些,用單純的原生非常難以實現(xiàn),而用自定義view,簡直分分鐘2021-11-11Kotlin?Dispatchers協(xié)程調(diào)度器源碼深入分析
Kotlin協(xié)程不是什么空中閣樓,Kotlin源代碼會被編譯成class字節(jié)碼文件,最終會運行到虛擬機中。所以從本質(zhì)上講,Kotlin和Java是類似的,都是可以編譯產(chǎn)生class的語言,但最終還是會受到虛擬機的限制,它們的代碼最終會在虛擬機上的某個線程上被執(zhí)行2022-11-11Flutter?Widget?之FocusableActionDetector使用詳解
這篇文章主要為大家介紹了Flutter?Widget?之FocusableActionDetector使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11