android 根据bounds坐标进行点击操作_炫酷的Android时钟UI控件,隔壁产品都馋哭了...
生活随笔
收集整理的這篇文章主要介紹了
android 根据bounds坐标进行点击操作_炫酷的Android时钟UI控件,隔壁产品都馋哭了...
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
廢話不多說,先上效果效果酷炫,動畫豐富,效果爆炸boom~設計思路看膩了市面上各種丑陋難看的時鐘控件,是時候整點新活!將現實生活中的擺鐘圓形表盤設計、電子手表的數顯表盤設計抽象出來,提取出“圓形”、“數顯”、“時光流逝感”等詞匯,融合這些詞匯特征,把特征賦予最終的UI設計......就這樣,一個炫酷的UI控件誕生了!撥動時鐘圓盤可以調整時鐘,伴隨時間的流逝,撥動的圓盤還能自動回位,交互邏輯自然順暢。設置不同的主題色即可體現更多的內涵,“靜謐”、“夜晚”、“月夜”、“純凈”等等,控件設計本身的可擴展性非常好。實現方案設計思路清晰明確之后,就要考慮如何實現了。來人,上口號。?沒有人?比我?更懂??實現類設計從UI圖中可以觀察到,時鐘控件由四個大表盤組成,分別是上下午表盤、小時表盤、分鐘表盤、秒鐘表盤。在實現思路上首先考慮抽象出圓盤控件父類DiskView,其余表盤均繼承自DiskView即可。有了各種各樣的表盤,最后再用ViewGroup將其進行組裝。而DiskView作為基類,需要承擔動畫、拖動、點擊等交互的邏輯,同時還要具備表盤的公共屬性,例如表盤半徑radius、表盤旋轉角度degree等。public class DiskView extends View { private static final String TAG = "DiskView"; Context mContext; /** * 圓盤半徑 */ int mRadius = 0; /** * 手指第一次按下時的坐標 */ float startX, startY; /** * 當前手指按下點的坐標 */ float curX, curY; /** * 第一次手指按下的點與初始位置形成的夾角 */ int startDegree; /** * 手指按下的點與初始位置形成的夾角 */ int curDegree; /** * 圓盤當前位置相對初始位置的角度,初始位置角度為0度 */ int degree = 0; /** * 手指抬起后是否需要回歸原來的狀態 */ boolean isNeedReturn = true; ValueAnimator animator;}UI繪制有了坐標、角度、半徑、顏色等屬性定義,接下來考慮繪制。繪制采用canvas的圖形繪制api,計算好各個圖形的位置,賦予對應的顏色。調用rotate方法圍繞圓心繪制具有一定角度的文字。需要注意的是,繪制文字時要確保文字中線經過圓盤圓心。@Overrideprotected void onDraw(Canvas canvas) {????super.onDraw(canvas);????//畫圓盤????mPaint.setColor(diskColor);????canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);????//畫數字????mPaint.setColor(numColor);????Rect bounds = new Rect();????for (int i = 0; i < 60; i++) {????????if (i == minute) {????????????mPaint.setColor(selectNumColor);????????} else {????????????mPaint.setColor(numColor);????????}????????if (i % 10 != 0) {????????????if (i % 5 == 0) {????????????????canvas.drawCircle(mRadius, 2 * mRadius - textHeight * 3 / 2, DisplayUtils.sp2px(mContext, 20) / 4, mPaint);????????????} else {????????????????canvas.drawCircle(mRadius, 2 * mRadius - textHeight * 3 / 2, DisplayUtils.sp2px(mContext, 20) / 6, mPaint);????????????}????????} else {????????????mPaint.getTextBounds(i + "", 0, (i + "").length(), bounds);????????????textHeight = bounds.height();????????????canvas.drawText(i + "", mRadius - bounds.width() / 2, mRadius * 2 - bounds.height(), mPaint);????????}????????canvas.rotate(-6, mRadius, mRadius);????}}交互邏輯控件交互邏輯大部分都在onTouchEvent的回調中進行處理,分別對用戶的點擊、移動、抬起動作做針對性處理,核心關鍵在于計算好各個情況的圓盤角度,之后再通過animator計算好對應的數值,實時刷新界面即可。需要注意的是用戶的起始落點不能超過圓盤的界限,在單獨使用某一個圓盤控件時要考慮邊界限制。@Overridepublic boolean onTouchEvent(MotionEvent event) {????curX = event.getX();????curY = event.getY();????switch (event.getAction()) {????????case MotionEvent.ACTION_DOWN:????????????startX = event.getX();????????????startY = event.getY();????????????startDegree = computeCurrentAngle(curX, curY);????????????//起始落點不能超過圓盤界限????????????if (Math.sqrt(????????????????????(startX - mRadius) * (startX - mRadius) + (startY - mRadius) * (startY - mRadius)????????????) > mRadius) {????????????????startDegree = 0;????????????}????????????break;????????case MotionEvent.ACTION_MOVE:????????????//起始落點不能超過圓盤界限????????????if (Math.sqrt(????????????????????(startX - mRadius) * (startX - mRadius) + (startY - mRadius) * (startY - mRadius)????????????) > mRadius) {????????????????return false;????????????}????????????curDegree = computeCurrentAngle(curX, curY);????????????postInvalidate();????????????break;????????case MotionEvent.ACTION_UP:????????????if (Math.sqrt(????????????????????(startX - mRadius) * (startX - mRadius) + (startY - mRadius) * (startY - mRadius)????????????) > mRadius) {????????????????return false;????????????}????????????int tmpDegree = degree;//手指按下前的圓盤角度????????????degree = degree + curDegree - startDegree;????????????if (Math.abs(degree) > 360) {????????????????degree %= 360;????????????}????????????startDegree = 0;????????????curDegree = 0;????????????startX = 0;????????????startY = 0;????????????//是否需要回位????????????if (isNeedReturn) {????????????????animator = ValueAnimator.ofInt(degree, tmpDegree);????????????????animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {????????????????????@Override????????????????????public void onAnimationUpdate(ValueAnimator animation) {????????????????????????degree = (int) animation.getAnimatedValue();????????????????????????postInvalidate();????????????????????}????????????????});????????????????animator.setDuration(200);????????????????animator.setInterpolator(new DecelerateInterpolator());????????????????animator.start();????????????}????????????break;????}????return true;}后記自定義控件開發作為Android開發中的重要一環,如何利用好各個api實現功能是一方面,如何自頂向下進行設計才是重點。在開發之前最關鍵的事情并不是構思如何實現、如何設計,而是去發掘用戶的需求,從需求倒推功能,再從功能角度考慮如何進行設計,最終呈現給用戶。
技術交流,歡迎加我微信:ezglumes ,拉你入技術交流群。
推薦閱讀:
音視頻面試基礎題
OpenGL ES 學習資源分享
開通專輯 | 細數那些年寫過的技術文章專輯
NDK 學習進階免費視頻來了
推薦幾個堪稱教科書級別的 Android 音視頻入門項目
覺得不錯,點個在看唄~
總結
以上是生活随笔為你收集整理的android 根据bounds坐标进行点击操作_炫酷的Android时钟UI控件,隔壁产品都馋哭了...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 拼接wav,将两个Wav文件合并
- 下一篇: 机器人最新天赋符文天赋加点图_常德202