仿Timely时间选择控件

编程入门 行业动态 更新时间:2024-10-09 17:29:04

仿Timely时间选择<a href=https://www.elefans.com/category/jswz/34/1769529.html style=控件"/>

仿Timely时间选择控件

Timely简介

焕彩闹钟是一款专为Android设计的华丽时钟,这款软件拥有惊艳的用户体验和革命性的云服务支持,允许对闹钟数据的备份从而在不同设备之间同步。
设置闹钟从未如此简单:只需从屏幕的边缘滑过,再通过拖动便可设置所需的闹钟时间。单次点击可进行以5分钟为单位的微调。
舒心的叫醒体验:精心打造的高品质闹铃和创新的智能叫醒功能,让您在早上醒来时神清气爽。
您的品味,您的风格:从我们绚丽的色彩主题中选择符合您的品味和风格, 或使用我们的设计工具来创造新的主题。您同样也可选择多个由设计师精心制作的时钟样式。
从此再也不迟到:新颖的解除闹钟方式确保您在解除闹钟时确实清醒。按下按钮不够炫酷?翻转手机来推迟闹钟。此外,当您拿起您的手机时,焕彩闹钟将自动减小闹钟音量来减轻闹钟音量。

说了这么多,其实也就是一个好看的那种而已,下面来展示一个她美丽的时间设置界面


效果展示

自定义控件的效果如下,虽然没有完全实现,但是大体的效果也是差不多的,这里最小的单位我设置的10分,没有具体到每分钟

理清思路

刚开始也是走了一些弯路的,想通过一个类似于水果手机中闹钟时间选择的效果来编写,但是搞了一天发现实现的效果不是很好,在滑动的时候,整个界面都会跟着动,最后只好放弃,换一个思路,通过类似于ProcessBar的方式来编写,那么什么是ProcessBar,就是下面的效果。

就是这样一个调节音量的效果了,很easy,我们得到滑块的位置,然后根据其所占的比例进行时间的换算,最后进行重新的绘制就可以了。

代码分析

这里最关键的就是两个方法了,一个是触摸事件相应的方法,一个是界面绘制的方法。

触摸时间相应

首先进行边界的判断,然后根据触摸的位置,做出相应并调用setProgress方法,我们在这个方法中调用invalidate()进行UI界面的重新绘制。

    public boolean onTouchEvent(MotionEvent event) {if (event.getY() < pointRadius) {setProgress(PROGRESS_MIN);return true;} else if (event.getY() > getHeight() - pointRadius) {setProgress(PROGRESS_MAX);return true;} else {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:setProgress(calculProgress(event.getY()));return true;case MotionEvent.ACTION_MOVE:setProgress(calculProgress(event.getY()));return true;}}return super.onTouchEvent(event);}
UI界面的绘制

这里我把数据写死了,其实完全可以将数据进行一下封装,使用接口的方式从外面传进来,UI界面的绘制还要注意屏幕适配的问题,代码的上面是时间轴效果的绘制,中间是一个简单动画效果的实现,下面是时间效果的绘制效果。

    public void draw(Canvas canvas) {Log.d(TAG, "[draw] .. in .. ");super.draw(canvas);linePaint = new Paint();linePaint.setAntiAlias(true);linePaint.setStyle(Paint.Style.FILL);linePaint.setStrokeWidth(lineHeight);linePaint.setColor(getResources().getColor(lineClor));String[] seq = new String[]{"-00", "-01", "-02", "-03", "-04", "-05", "-06", "-07", "-08","-09", "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17","-18", "-19", "-20", "-21", "-22", "-23", "-24"};//因为是以画布Canvas 为draw对象,所以RectF构造函数内的参数是以canvas为边界,而不是屏幕//画线以及动画效果的实现for(int i = 0; i < seq.length; i++){if(i < mThisHour-3 || i > mThisHour+3) {linePaint.setTextSize(30);canvas.drawText(seq[i], getWidth() / 2, getHeight() / 24 * (24 - i), linePaint);}else if(i == mThisHour+3 || i == mThisHour-3){linePaint.setTextSize(35);canvas.drawText(seq[i], getWidth() / 2 + 10, getHeight() / 24 * (24 - i), linePaint);}else if(i == mThisHour+2 || i == mThisHour-2){linePaint.setTextSize(40);canvas.drawText(seq[i], getWidth() / 2 + 20, getHeight() / 24 * (24 - i), linePaint);}else if(i == mThisHour+1 || i == mThisHour-1){linePaint.setTextSize(45);canvas.drawText(seq[i], getWidth() / 2 + 30, getHeight() / 24 * (24 - i), linePaint);}else{linePaint.setTextSize(50);canvas.drawText(seq[i], getWidth() / 2 + 40, getHeight() / 24 * (24 - i), linePaint);}}//时间效果的实现pointPaint = new Paint();pointPaint.setAntiAlias(true);pointPaint.setStyle(Paint.Style.FILL);pointPaint.setColor(getResources().getColor(pointColor));pointPaint.setTextSize(100);canvas.drawText(progressToTime(100 - progress),getWidth()/2+200, getCx()+10, pointPaint);}

可能通过上面的两个方法还不能完全理解,下面是自定义控件的完整代码,也可以从最下面的链接下载,直接运行查看效果即可

package com.iigt.myscoleftview.view;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;import com.iigt.myscoleftview.R;/*** Created by zhouheng on 2017/3/28.*/public class MyScrollView extends View {private static final String TAG = "TouchProgressView";private Paint linePaint;private Paint pointPaint;private int pointRadius = 10;//圆点默认半径,单位pxprivate int pointColor = R.color.gray_dft;//圆点默认颜色private int lineHeight = 2;//线默认高度,单位pxprivate int lineClor = R.color.gray_dft;//线默认颜色private int progress = 0;private final int PROGRESS_MIN = 0;private final int PROGRESS_MAX = 100;private OnProgressChangedListener progressChangedListener;private int mThisHour;private int mThisMin;public interface OnProgressChangedListener {void onProgressChanged(View view, int progress);}public MyScrollView(Context context) {super(context, null);}public MyScrollView(Context context, AttributeSet attrs) {super(context, attrs);}public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}/*** 设置百分比** @param progress*/public void setProgress(int progress) {if (progress < 0 || progress > 100) {throw new IllegalArgumentException("progress 不可以小于0 或大于100");}this.progress = progress;invalidate();if (progressChangedListener != null) {progressChangedListener.onProgressChanged(this, 100-progress);}}/*** 设置进度变化监听器** @param onProgressChangedListener*/public void setOnProgressChangedListener(OnProgressChangedListener onProgressChangedListener) {this.progressChangedListener = onProgressChangedListener;}@Overridepublic boolean onTouchEvent(MotionEvent event) {if (event.getY() < pointRadius) {setProgress(PROGRESS_MIN);return true;} else if (event.getY() > getHeight() - pointRadius) {setProgress(PROGRESS_MAX);return true;} else {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:setProgress(calculProgress(event.getY()));return true;case MotionEvent.ACTION_MOVE:setProgress(calculProgress(event.getY()));return true;}}return super.onTouchEvent(event);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);}@Overridepublic void draw(Canvas canvas) {Log.d(TAG, "[draw] .. in .. ");super.draw(canvas);linePaint = new Paint();linePaint.setAntiAlias(true);linePaint.setStyle(Paint.Style.FILL);linePaint.setStrokeWidth(lineHeight);linePaint.setColor(getResources().getColor(lineClor));String[] seq = new String[]{"-00", "-01", "-02", "-03", "-04", "-05", "-06", "-07", "-08","-09", "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17","-18", "-19", "-20", "-21", "-22", "-23", "-24"};//因为是以画布Canvas 为draw对象,所以RectF构造函数内的参数是以canvas为边界,而不是屏幕//画线以及动画效果的实现for(int i = 0; i < seq.length; i++){if(i < mThisHour-3 || i > mThisHour+3) {linePaint.setTextSize(30);canvas.drawText(seq[i], getWidth() / 2, getHeight() / 24 * (24 - i), linePaint);}else if(i == mThisHour+3 || i == mThisHour-3){linePaint.setTextSize(35);canvas.drawText(seq[i], getWidth() / 2 + 10, getHeight() / 24 * (24 - i), linePaint);}else if(i == mThisHour+2 || i == mThisHour-2){linePaint.setTextSize(40);canvas.drawText(seq[i], getWidth() / 2 + 20, getHeight() / 24 * (24 - i), linePaint);}else if(i == mThisHour+1 || i == mThisHour-1){linePaint.setTextSize(45);canvas.drawText(seq[i], getWidth() / 2 + 30, getHeight() / 24 * (24 - i), linePaint);}else{linePaint.setTextSize(50);canvas.drawText(seq[i], getWidth() / 2 + 40, getHeight() / 24 * (24 - i), linePaint);}}//时间效果的实现pointPaint = new Paint();pointPaint.setAntiAlias(true);pointPaint.setStyle(Paint.Style.FILL);pointPaint.setColor(getResources().getColor(pointColor));pointPaint.setTextSize(100);canvas.drawText(progressToTime(100 - progress),getWidth()/2+200, getCx()+10, pointPaint);}/*** 将百分比转换成时间* @param progress 输入的百分比* @return 返回对应的时间*/private String progressToTime(float progress){float myMin = (6.0f * 24.0f) / 100;float thisTime = progress * myMin;mThisHour = ((int)thisTime) / 6;mThisMin = ((int)thisTime) % 6;return Integer.toString(mThisHour) + ": "+ Integer.toString(mThisMin) + "0";}/*** 获取圆点的x轴坐标** @return*/private float getCx() {float cx = 0.0f;cx = (getHeight() - pointRadius * 2);if (cx < 0) {throw new IllegalArgumentException("TouchProgressView 宽度不可以小于 2 倍 pointRadius");}return cx / 100 * (progress) + pointRadius;}/*** 计算触摸点的百分比** @param eventX* @return*/private int calculProgress(float eventX) {float proResult = (eventX - pointRadius) / (getHeight() - pointRadius * 2);return (int) (proResult * 100);}}

Demo下载地址:

更多推荐

仿Timely时间选择控件

本文发布于:2024-02-06 11:57:43,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1748870.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:控件   时间   Timely

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!