網站首頁 編程語言 正文
本文實例為大家分享了Android自定義View實現時鐘效果的具體代碼,供大家參考,具體內容如下
自定義時鐘
初學自定義View,先畫一個不太成熟的時鐘(甚至只有秒針)
時鐘效果
@SuppressLint("DrawAllocation") public class ClockView extends View { ? ? private final Context mContext; ? ? private Canvas mCanvas;// 畫布 ? ? private Paint clockPaint;// 表盤畫筆 ? ? private Paint textPaint;// 文字畫筆 ? ? private Paint secondPaint;// 秒針畫筆 ? ? private int x,y;// 表中心坐標 ? ? private Thread refreshThread; ? ? private boolean isStop = false; ? ? // 用于獲取當前秒數 ? ? private ?Date currentDate; ? ? private SimpleDateFormat sp = new SimpleDateFormat("ss"); ? ? @SuppressLint("HandlerLeak") ? ? private final Handler mHandler = new Handler(){ ? ? ? ? @Override ? ? ? ? public void handleMessage(@NonNull Message msg) { ? ? ? ? ? ? super.handleMessage(msg); ? ? ? ? ? ? if(msg.what == 0){ ? ? ? ? ? ? ? ? invalidate();//每隔一秒刷新一次 ? ? ? ? ? ? } ? ? ? ? } ? ? }; ? ? public ClockView(Context context) { ? ? ? ? this(context,null); ? ? } ? ? public ClockView(Context context, @Nullable AttributeSet attrs) { ? ? ? ? this(context,null,0); ? ? } ? ? public ClockView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { ? ? ? ? this(context,null,0,0); ? ? } ? ? public ClockView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { ? ? ? ? super(context, attrs, defStyleAttr, defStyleRes); ? ? ? ? this.mContext = context; ? ? } ? ? @Override ? ? protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { ? ? ? ? int widthMeasure; ? ? ? ? // 設置寬高一致 ? ? ? ? if(widthMeasureSpec > heightMeasureSpec){ ? ? ? ? ? ? super.onMeasure(heightMeasureSpec, heightMeasureSpec); ? ? ? ? ? ? widthMeasure ?= getMeasuredHeight(); ? ? ? ? }else{ ? ? ? ? ? ? super.onMeasure(widthMeasureSpec, widthMeasureSpec); ? ? ? ? ? ? widthMeasure = getMeasuredWidth(); ? ? ? ? } ? ? ? ? initPaint(widthMeasure); ? ? } ? ? private void initPaint(int width){ ? ? ? ? // 表盤畫筆 ? ? ? ? clockPaint = new Paint(); ? ? ? ? clockPaint.setColor(mContext.getColor(R.color.black));// 顏色 ? ? ? ? clockPaint.setAntiAlias(true);// 抗鋸齒 ? ? ? ? clockPaint.setStyle(Paint.Style.STROKE);// 樣式 ? ? ? ? clockPaint.setStrokeWidth(width/80f);// 寬度 ? ? ? ? //字體畫筆 ? ? ? ? textPaint = new Paint(); ? ? ? ? textPaint.setColor(mContext.getColor(R.color.black)); ? ? ? ? textPaint.setAntiAlias(true); ? ? ? ? textPaint.setStyle(Paint.Style.FILL); ? ? ? ? textPaint.setTextSize(width/16f); ? ? ? ? textPaint.setTextAlign(Paint.Align.CENTER); ? ? ? ? // 秒針畫筆 ? ? ? ? secondPaint = new Paint(); ? ? ? ? secondPaint.setColor(mContext.getColor(R.color.red)); ? ? ? ? secondPaint.setAntiAlias(true); ? ? ? ? secondPaint.setStyle(Paint.Style.FILL); ? ? ? ? secondPaint.setStrokeWidth(5f); ? ? } ? ? @Override ? ? protected void onDraw(Canvas canvas) { ? ? ? ? super.onDraw(canvas); ? ? ? ? mCanvas = canvas; ? ? ? ? // 獲取畫布中心坐標 ? ? ? ? x = getWidth() / 2; ? ? ? ? y = getHeight() / 2; ? ? ? ? // 繪制表盤 ? ? ? ? mCanvas.drawCircle(x, y,getWidth()/40f, clockPaint);// 表盤中心 ? ? ? ? mCanvas.drawCircle(x, y, x -getWidth()/40f, clockPaint);// 表盤邊框 ? ? ? ? // 繪制刻度 ? ? ? ? for(int i = 1;i <= 60;i++){ ? ? ? ? ? ? mCanvas.rotate(6, x, y); ? ? ? ? ? ? if(i%5 == 0){ ? ? ? ? ? ? ? ? // 繪制大刻度 ? ? ? ? ? ? ? ? mCanvas.drawLine(x, getWidth()*3/80f, x, getWidth()*5/80f, clockPaint); ? ? ? ? ? ? }else{ ? ? ? ? ? ? ? ? // 繪制小刻度 ? ? ? ? ? ? ? ? mCanvas.drawLine(x, getWidth()*3/80f, x, getWidth()/20f, clockPaint); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? // 繪制 1-12小時 字體 ? ? ? ? for(int i = 1;i <= 60;i++){ ? ? ? ? ? ? if(i%5 == 0){ ? ? ? ? ? ? ? ? float x1 = (float) Math.sin(Math.toRadians(6 * i)) * (y * 3 / 4f) + x; ? ? ? ? ? ? ? ? float y1 = y - (float) Math.cos(Math.toRadians(6 * i)) * (y * 3 / 4f) + getWidth()/40f; ? ? ? ? ? ? ? ? mCanvas.drawText(String.valueOf(i/5), x1, y1, textPaint); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? // 繪制秒針 ? ? ? ? currentDate = new Date(System.currentTimeMillis()); ? ? ? ? int ss = Integer.parseInt(sp.format(currentDate));// 獲取當前秒數 ? ? ? ? // 根據當前秒數 計算出秒針的 start 及 end 坐標 ? ? ? ? float sin = (float) Math.sin(Math.toRadians(6 * ss)); ? ? ? ? float cos = (float) Math.cos(Math.toRadians(6 * ss)); ? ? ? ? float x0 = x - sin * (y / 10f); ? ? ? ? float y0 = y + cos * (y / 10f); ? ? ? ? float x1 = x + sin * (y * 13 / 20f); ? ? ? ? float y1 = y - cos * (y * 13 / 20f); ? ? ? ? mCanvas.drawLine(x0, y0, x1, y1, secondPaint); ? ? ? ? mCanvas.drawCircle(x, y,getWidth()/80f, secondPaint); ? ? } ? ? @Override ? ? protected void onAttachedToWindow() { ? ? ? ? super.onAttachedToWindow(); ? ? ? ? refreshThread = new Thread(){ ? ? ? ? ? ? @Override ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? super.run(); ? ? ? ? ? ? ? ? while (!isStop){ ? ? ? ? ? ? ? ? ? ? SystemClock.sleep(1000); ? ? ? ? ? ? ? ? ? ? mHandler.sendEmptyMessage(0); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? }; ? ? ? ? refreshThread.start(); ? ? } ? ? @Override ? ? protected void onDetachedFromWindow() { ? ? ? ? super.onDetachedFromWindow(); ? ? ? ? mHandler.removeCallbacksAndMessages(null); ? ? ? ? isStop = true; ? ? }
原文鏈接:https://blog.csdn.net/yubaba111/article/details/122432423
相關推薦
- 2023-02-17 python引入其他py文件或模塊_python
- 2022-09-17 C++?中封裝的含義和簡單實現方式_C 語言
- 2022-04-09 SpringBoot文件上傳, 上傳到項目的相對路徑上
- 2022-07-27 Python編寫條件分支代碼方法_python
- 2022-05-13 ERROR org.apache.hadoop.hdfs.server.datanode.DataN
- 2022-06-06 淺談Redis?中的過期刪除策略和內存淘汰機制_Redis
- 2022-01-29 win server 2008 web IIS部署asp.net程序后,CSS樣式錯亂不顯示問題
- 2022-03-29 Python?dict的使用誤區你知道嗎_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支