国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android編程基于自定義控件實現時鐘功能的方法

2019-10-22 18:14:18
字體:
來源:轉載
供稿:網友

本文實例講述了Android編程基于自定義控件實現時鐘功能的方法。分享給大家供大家參考,具體如下:

在學習安卓群英傳自定義控件章節的時候,有一個例子是繪制時鐘,在實現了書上的例子后就想看這個時鐘能不能動起來。

這里選擇延遲一秒發送消息重繪view來實現的動畫,對外提供了開啟時鐘,關閉時鐘的方法,當activity執行onResume方法的時候,執行startClock()方法,當移除view或activity執行onStop方法的時候可以執行stopClock()方法。

首先根據view的寬高來確定圓心的位置,并畫出一個圓。再通過view高度的一半減去圓的半徑,確定刻度的起始位置,選擇刻度的長度并繪制出來。然后再刻度下方繪制出數字。最終將畫布進行旋轉,時鐘總共有60個刻度,循環旋轉,每次旋轉6度即可。

最后是繪制指針,通過計算算出指針對應每個刻度的X,Y坐標并繪制直線。

Android,自定義控件,時鐘

代碼實現

自定義控件的代碼(ClockView.java):

package com.example.clock;import java.util.Calendar;import java.util.Date;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.util.AttributeSet;import android.view.View;public class ClockView extends View {  private Paint circlePaint, dialPaint, numberPaint;  // view 的寬高  private float mWidth, mHeight;  // 圓的半徑  private float circleRadius;  // 圓心X,Y坐標  private float circleX, circleY;  private int second, minute;  private double hour;  private Handler handler = new Handler(Looper.getMainLooper()) {    @Override    public void handleMessage(Message msg) {      super.handleMessage(msg);      if (msg.what == 0) {        invalidate();      }    }  };  public ClockView(Context context, AttributeSet attrs) {    super(context, attrs);    initPaint();  }  private void initPaint() {    // 刻盤圓,小時刻度,時針和分針的畫筆    circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);    circlePaint.setColor(Color.BLACK);    circlePaint.setStyle(Paint.Style.STROKE);    circlePaint.setStrokeWidth(10);    // 分鐘刻度的畫筆    dialPaint = new Paint(Paint.ANTI_ALIAS_FLAG);    dialPaint.setColor(Color.BLACK);    dialPaint.setStrokeWidth(5);    // 數字的畫筆    numberPaint = new Paint(Paint.ANTI_ALIAS_FLAG);    numberPaint.setColor(Color.BLACK);    numberPaint.setStrokeWidth(5);    numberPaint.setTextSize(30);  }  @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    super.onMeasure(widthMeasureSpec, heightMeasureSpec);    mWidth = getMeasuredWidth();    mHeight = getMeasuredHeight();    if (mWidth < mHeight) {      // 圓的半徑為view的寬度的一半再減9,防止貼邊      circleRadius = mWidth / 2 - 9;      circleX = mWidth / 2;      circleY = mHeight / 2;    } else {      circleRadius = mHeight / 2 - 9;      circleX = mWidth / 2;      circleY = mHeight / 2;    }  }  @Override  protected void onDraw(Canvas canvas) {    super.onDraw(canvas);    setTimes();    drawCirclePoint(canvas);    drawCircle(canvas);    drawDial(canvas);    drawPointer(canvas);  }  /**   * 圓心   *    * @param canvas   */  private void drawCirclePoint(Canvas canvas) {    canvas.drawCircle(circleX, circleY, 5, circlePaint);  }  private void drawCircle(Canvas canvas) {    canvas.drawCircle(circleX, circleY, circleRadius, circlePaint);  }  /**   * 畫刻度及時間   *    * @param canvas   */  private void drawDial(Canvas canvas) {    // 時鐘用長一點的刻度,畫筆用畫圓的畫筆    Point hourStartPoint = new Point(circleX, circleY - circleRadius);    Point hourEndPoint = new Point(circleX, circleY - circleRadius + 40);    // 分鐘的刻度要稍微短一些,畫筆用畫圓的畫筆    Point startPoint2 = new Point(circleX, circleY - circleRadius);    Point endPoint2 = new Point(circleX, circleY - circleRadius + 10);    // 開始畫刻度和數字,總共60個刻度,12個時鐘刻度,被5整除畫一個時鐘刻度,被其余的為分針刻度    String clockNumber;    for (int i = 0; i < 60; i++) {      if (i % 5 == 0) {        if (i == 0) {          clockNumber = "12";        } else {          clockNumber = String.valueOf(i / 5);        }        // 時針刻度        canvas.drawLine(hourStartPoint.getX(), hourStartPoint.getY(),            hourEndPoint.getX(), hourEndPoint.getY(), circlePaint);        // 畫數字,需在時針刻度末端加30        canvas.drawText(clockNumber,            circleX - numberPaint.measureText(clockNumber) / 2,            hourEndPoint.getY() + 30, numberPaint);      } else {        // 畫分針刻度        canvas.drawLine(startPoint2.getX(), startPoint2.getY(),            endPoint2.getX(), endPoint2.getY(), circlePaint);      }      // 畫布旋轉6度      canvas.rotate(360 / 60, circleX, circleY);    }  }  /**   * 畫指針 X點坐標 cos(弧度)*r Y點坐標 sin(弧度)*r toRadians將角度轉成弧度   * 安卓坐標系與數學坐標系不同的地方是X軸是相反的,所以為了調整方向,需要將角度+270度   *    * @param canvas   */  private void drawPointer(Canvas canvas) {    canvas.translate(circleX, circleY);    float hourX = (float) Math.cos(Math.toRadians(hour * 30 + 270))        * circleRadius * 0.5f;    float hourY = (float) Math.sin(Math.toRadians(hour * 30 + 270))        * circleRadius * 0.5f;    float minuteX = (float) Math.cos(Math.toRadians(minute * 6 + 270))        * circleRadius * 0.8f;    float minuteY = (float) Math.sin(Math.toRadians(minute * 6 + 270))        * circleRadius * 0.8f;    float secondX = (float) Math.cos(Math.toRadians(second * 6 + 270))        * circleRadius * 0.8f;    float secondY = (float) Math.sin(Math.toRadians(second * 6 + 270))        * circleRadius * 0.8f;    canvas.drawLine(0, 0, hourX, hourY, circlePaint);    canvas.drawLine(0, 0, minuteX, minuteY, circlePaint);    canvas.drawLine(0, 0, secondX, secondY, dialPaint);    // 一秒重繪一次    handler.sendEmptyMessageDelayed(0, 1000);  }  public void startClock() {    setTimes();    invalidate();  }  private void setTimes() {    Date date = new Date();    Calendar calendar = Calendar.getInstance();    calendar.setTime(date);    second = getTimes(date, Calendar.SECOND);    minute = getTimes(date, Calendar.MINUTE);    hour = getTimes(date, Calendar.HOUR) + minute / 12 * 0.2;  }  private int getTimes(Date date, int calendarField) {    Calendar calendar = Calendar.getInstance();    calendar.setTime(date);    return calendar.get(calendarField);  }  public void stopClock() {    handler.removeMessages(0);  }}

Point.java:

package com.example.clock;public class Point {  private float x;  private float y;  public Point(float x, float y) {    this.x = x;    this.y = y;  }  public float getX() {    return x;  }  public void setX(float x) {    this.x = x;  }  public float getY() {    return y;  }  public void setY(float y) {    this.y = y;  }}

Acitivity(ClockActivity.java):

package com.example.clock;import android.app.Activity;import android.os.Bundle;public class ClockActivity extends Activity {  /** Called when the activity is first created. */  private ClockView clockView;  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);    clockView = (ClockView) findViewById(R.id.clock);  }  @Override  protected void onResume() {    super.onResume();    clockView.startClock();  }  @Override  protected void onStop() {    super.onStop();    clockView.stopClock();  }}

xml布局(main.xml):

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:orientation="vertical"  android:layout_width="match_parent"  android:gravity="center"  android:layout_height="match_parent">  <com.example.customview.view.ClockView    android:layout_width="match_parent"    android:id="@+id/clock"    android:layout_height="match_parent" /></LinearLayout>

希望本文所述對大家Android程序設計有所幫助。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 兴国县| 沙田区| 寿光市| 门源| 宽城| 宣城市| 吉隆县| 德化县| 当涂县| 高州市| 昌都县| 缙云县| 双辽市| 塘沽区| 芷江| 郁南县| 古田县| 辽源市| 东山县| 绵阳市| 定襄县| 芜湖县| 高州市| 上栗县| 丰县| 龙口市| 雷波县| 江城| 大理市| 监利县| 枣阳市| 清徐县| 华池县| 纳雍县| 龙岩市| 桂林市| 阜南县| 诸城市| 泰州市| 盘锦市| 阿鲁科尔沁旗|