Android 自定义View入门学习(一):自定义一个简单的时钟

 

 

今天我们来一起学习一下怎么通过自定义view画一个时钟出来。

自定义view是一个比较有意思,同时难度也是很高的工作。现在市面上有很多动画效果很棒的页面,无非都是一步一步从最基础的学起的,正所谓万丈高楼平地起。所以,这篇文章很适合新手入门练习哦。

首先先贴上最终的效果图吧,这样到时看代码不会特别抽象。

下面我说一下,实现的步骤是什么吧。

  1. 画一个外圆(确定圆心位置,然后给一个半径)
  2. 画刻度(将圆等分成12部分,先画处0点的位置,最后通过画布的旋转,旋转的角度的360/12,画刻度直线)
  3. 画时针和分针(把手机的坐标原点移动到圆的中心点,再画2条直线,一个时针和分针)

下面贴上代码:

 

package com.example.myapplication.view;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;public class CustomClockView extends View {private Paint circlePaint, keduPaint, hourPaint, minuterPaint;public CustomClockView(Context context) {this(context, null);}public CustomClockView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CustomClockView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);//圆circlePaint = new Paint();circlePaint.setColor(Color.BLACK);circlePaint.setStyle(Paint.Style.STROKE);circlePaint.setStrokeWidth(10);//刻度keduPaint = new Paint();keduPaint.setColor(Color.BLACK);circlePaint.setStrokeWidth(3);circlePaint.setStyle(Paint.Style.STROKE);//时针和分针hourPaint = new Paint(Paint.ANTI_ALIAS_FLAG);hourPaint.setStrokeWidth(15);hourPaint.setStyle(Paint.Style.STROKE);hourPaint.setColor(Color.BLACK);minuterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);minuterPaint.setStrokeWidth(8);minuterPaint.setStyle(Paint.Style.STROKE);minuterPaint.setColor(Color.BLACK);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);//防止在xml输入wrap_content导致布局变形//设置为始终保持正方形int width = MeasureSpec.getSize(widthMeasureSpec);int height = MeasureSpec.getSize(heightMeasureSpec);setMeasuredDimension(width > height ? height : width, height > width ? width : height);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//画一个圆canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 4, circlePaint);//画刻度for (int i = 0; i < 12; i++) {if (i == 0 || i == 3 || i == 6 || i == 9) {keduPaint.setStrokeWidth(6);keduPaint.setTextSize(40);//画刻度canvas.drawLine(getWidth() / 2, getHeight() / 2 - getWidth() / 4, getWidth() / 2, getHeight() / 2 - getWidth() / 4 + 50, keduPaint);//画时间String timeText = String.valueOf(i);canvas.drawText(timeText, getWidth() / 2 - keduPaint.measureText(timeText) / 2, getHeight() / 2 - getWidth() / 4 + 80, keduPaint);} else {keduPaint.setStrokeWidth(3);keduPaint.setTextSize(20);//画刻度canvas.drawLine(getWidth() / 2, getHeight() / 2 - getWidth() / 4, getWidth() / 2, getHeight() / 2 - getWidth() / 4 + 25, keduPaint);//画时间String timeText = String.valueOf(i);canvas.drawText(timeText, getWidth() / 2 - keduPaint.measureText(timeText) / 2, getHeight() / 2 - getWidth() / 4 + 80, keduPaint);}canvas.rotate(30, getWidth() / 2, getHeight() / 2);}//画布平移到中点canvas.translate(getWidth()/2,getHeight()/2);//画时针canvas.drawLine(0, 0, 100 , 0, hourPaint);//画分针canvas.drawLine(0, 0, 0, 130, minuterPaint);}
}

下面介绍一下其中比较重要的api吧

画一条直线:
canvas.drawLine(float startX, float startY, float stopX, float stopY, @NonNull Paint paint)
  1. starX: 开始时XX坐标
  2. startY:开始时的Y坐标
  3. stopX:结束时的X坐标
  4. stopY:结束时的Y坐标
  5. paint :这条直线的画笔(我们可以通过画笔设置一些颜色,字体大小,宽度,等参数)

 画圆:

canvas.drawCircle(float cx, float cy, float radius, @NonNull Paint paint)
  1. cx:原点X坐标位置
  2. cy:原点Y坐标位置
  3. radius:半径
  4. paint:圆的画笔

画文字:

canvas.drawText(@NonNull String text, float x, float y, @NonNull Paint paint)
  1. text:需要画的文字
  2. x:开始画字的x坐标
  3. y:开始画字的y坐标
  4. paint:字的画笔

 

画钟表上的文字的时候,要明白,其实就是在刻度的终点画这个文字,然后我们要使文字稍微居中一点,可以这样:

开始画字的X坐标 - paint.measureText()/2 ;

旋转:

canvas.rotate(float degrees, float px, float py);

  1. degress:旋转的角度
  2. px:旋转的原点X
  3. py:旋转的原点Y
平移:
canvas.translate(float dx, float dy);

手机的坐标原点都是在左上角的位置,这个方法是把这个手机的原始坐标点,移动到另一个点,作为手机的左上角,再开始计算位置的。


最后贴上布局文件:

结束,下班。哈哈。这是入门的第一个,后面我还会继续出更多的自定义view和大家一起学习,大家一起成长哦。

 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部