Android 尺子效果,根据时间支持左右滑动(原创)

过完年,到现在也没有认真的写代码,正好公司有需求,花了一个下午,写了一个尺子效果的自定义View,效果还行,但是还有很多需要改进的地方,希望大家指正!!!可以左右滑动,下面是关键代码!!

package com.example.drawrulerview;

import OnCustomRurleListener.OnCustomViewListener;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.PorterDuff.Mode;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toolbar;

@SuppressLint("NewApi")
public class CustomRuleView extends View {
	private final int NUM = 4;// 整个屏幕宽度内要显示的几个条数
	private Canvas mCanvas;
	private Paint mPaint;
	private int mViewWidth;
	private int mViewHeight;
	private String middleStrTime;
	private double millsWidthPrecent;// 每一秒要代表的长度
	private double timePrecent;// 每一份长度要代表的时间(s)
	private float xStar, xEnd;

	public CustomRuleView(Context context, AttributeSet attrs) {

		super(context, attrs);
		initFirstData();
	}

	private void initFirstData() {
		// TODO Auto-generated method stub
		this.middleStrTime = Utils.timeLong2Date(System.currentTimeMillis());

	}

	private void initData() {
		if (mPaint == null) {
			mPaint = new Paint();
			mViewHeight = this.getHeight();
			mViewWidth = this.getWidth();
			millsWidthPrecent = mViewWidth / (NUM * 60 * 60 * 1.0);
			timePrecent = NUM * 60 * 60 * 1.0 / mViewWidth;
			Log.d("msg", "---prcetn:" + millsWidthPrecent);
		}

	}

	@Override
	protected void onDraw(Canvas canvas) {
		clear(canvas);
		initData();
		drawView(canvas);
		super.onDraw(canvas);
	}

	private void drawView(Canvas mCanvas) {
		this.mCanvas = mCanvas;
		drawMiddleLine();
		drawTextTopMiddle(middleStrTime);
		drawRuleDeg();
	}

	/**
	 * 清除界面
	 *
	 * @param mCanvas
	 */
	public void clear(Canvas mCanvas) {
		Paint paint = new Paint();
		paint.setXfermode(new PorterDuffXfermode(Mode.DST));
		mCanvas.drawPaint(paint);
	}

	/*
	 * 根据中间的刻度,画出其他刻度
	 */
	private void drawRuleDeg() {
		mPaint.setColor(Color.GRAY);
		mPaint.setTextSize(mViewHeight / 6);
		EntityConversionTime conversionTime = Utils
				.getCurrentTimeEntity(middleStrTime);
		// 距离下一个整点的时间(单位s)
		int nxteMissTmp = (60 - conversionTime.getMinNUM() - 1) * 60 + 60
				- conversionTime.getMillNUM();
		// 距离上一个整点的时间(单位s)
		int beforeMissTmp = conversionTime.getMinNUM() * 60
				+ conversionTime.getMillNUM();
		Log.d("msg", "---width:" + nxteMissTmp * millsWidthPrecent
				+ "  precent:" + millsWidthPrecent + "  realWidth:"
				+ mViewWidth);

		drawLineText((float) (mViewWidth / 2 + (nxteMissTmp)
				* millsWidthPrecent), conversionTime.getHourNUM() + 1);

		drawLineText((float) (mViewWidth / 2 + (nxteMissTmp + 3600)
				* millsWidthPrecent), conversionTime.getHourNUM() + 2);

		// 左边

		drawLineText((float) (mViewWidth / 2 - beforeMissTmp
				* millsWidthPrecent), conversionTime.getHourNUM());

		drawLineText((float) (mViewWidth / 2 - (beforeMissTmp + 3600)// 多一个周期
				* millsWidthPrecent), conversionTime.getHourNUM() - 1);

	}

	private void drawLineText(float left, int TvTime) {

		RectF rectF = new RectF(left - 20, mViewHeight / 3, left + 20,
				mViewHeight / 2);
		drawCeninView(rectF, mCanvas, mPaint, TvTime + ":00");

		mCanvas.drawLine(left, mViewHeight*2 / 3 -10, left, mViewHeight*2 / 3 ,
				mPaint);

	}

	private void drawTextTopMiddle(String tvStr) {

		this.middleStrTime = tvStr;
		mPaint.setColor(Color.WHITE);
		mPaint.setTextSize(mViewHeight / 4);
		RectF rectF = new RectF(0, 0, mViewWidth, mViewHeight / 3);
		drawCeninView(rectF, mCanvas, mPaint, tvStr);

	}

	/**
	 * 在矩形的中间绘制
	 *
	 * @param targetRect0
	 * @param canvas
	 * @param paint
	 * @param tvStr
	 */
	private void drawCeninView(RectF targetRect0, Canvas canvas, Paint paint,
			String tvStr) {
		FontMetricsInt fontMetrics = paint.getFontMetricsInt();
		int baseline = (int) (targetRect0.top
				+ (targetRect0.bottom - targetRect0.top - fontMetrics.bottom + fontMetrics.top)
				/ 2 - fontMetrics.top);
		paint.setTextAlign(Paint.Align.CENTER);
		canvas.drawText(tvStr, targetRect0.centerX(), baseline, paint);
	}

	/**
	 * 绘制中间的线
	 */
	private void drawMiddleLine() {
		// TODO Auto-generated method stub
		mPaint.setColor(Color.YELLOW);
		mPaint.setStrokeWidth(2);
		mCanvas.drawLine(mViewWidth / 2, 0, mViewWidth / 2, mViewHeight, mPaint);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {

		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.d("msg", "touching1");
			xStar = event.getX();
			break;
		case MotionEvent.ACTION_UP:
			Log.d("msg", "touching2");
			xEnd = 0;
			xStar = 0;
			break;
		case MotionEvent.ACTION_MOVE:

			xEnd = event.getX();

			drawViewTouch(xStar - xEnd);
			xStar = event.getX();
			break;

		default:
			break;
		}

		return super.onTouchEvent(event);

	}

	/**
	 * 滑动的时候调用的方法
	 *
	 * @param f
	 */
	private void drawViewTouch(float f) {

		Log.d("msg", "touching3:---->" + f);

		if (f != 0) {// 滑动调用相关的方法
			long time = (long) (Utils.date2TimeLong(middleStrTime) + timePrecent
					* f * 1000);
			middleStrTime = Utils.timeLong2Date(time);
		}

		Log.v("msg", "middleTime:" + middleStrTime);

		invalidate();
	}
}

  

package com.example.drawrulerview;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;

public class Utils {

	/**
	 * 1393445856--->2014-05-01 00:01:58
	 *
	 * @param time
	 * @return
	 */
	public static String timeLong2Date(long time) {

		DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return formatter.format(time);

	}
	/**
	 * 2014-05-01 00:01:58 --->1393445565
	 * @param time
	 * @return
	 */
	public static long date2TimeLong(String time) {
		Calendar c = Calendar.getInstance();

		try {
			c.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(time));
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return c.getTimeInMillis();
	}

	/**
	 * 获取当前日期的实体
	 *
	 * @return
	 */
	public static EntityConversionTime getCurrentTimeEntity(String strTime) {

		final Calendar c = Calendar.getInstance();
		c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
		try {
			c.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(strTime));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		EntityConversionTime entityConversionTime = new EntityConversionTime();
		entityConversionTime.setYearNUM(c.get(Calendar.YEAR));// 获取当前年份
		entityConversionTime.setMonthNUM(c.get(Calendar.MONTH) + 1);// 获取当前月份
		entityConversionTime.setDayNUM(c.get(Calendar.DAY_OF_MONTH));// 获取当前月份的日期号码
		String mWay = String.valueOf(c.get(Calendar.DAY_OF_WEEK));
		entityConversionTime.setHourNUM(c.get(Calendar.HOUR_OF_DAY));
		entityConversionTime.setMinNUM(c.get(Calendar.MINUTE));
		entityConversionTime.setMillNUM(c.get(Calendar.SECOND));

		int tmp = 1;
		if ("1".equals(mWay)) {
			tmp = 7;
		} else if ("2".equals(mWay)) {
			tmp = 1;
		} else if ("3".equals(mWay)) {
			tmp = 2;
		} else if ("4".equals(mWay)) {
			tmp = 3;
		} else if ("5".equals(mWay)) {
			tmp = 4;
		} else if ("6".equals(mWay)) {
			tmp = 5;
		} else if ("7".equals(mWay)) {
			tmp = 6;
		}

		entityConversionTime.setWeekNUM(tmp);
		tmp = entityConversionTime.getMonthNUM();
		if (tmp == 1 || tmp == 3 || tmp == 5 || tmp == 7 || tmp == 8
				|| tmp == 10 || tmp == 12) {// 31天
			tmp = 31;
		} else if (tmp == 2) {
			if (isLeapYear(entityConversionTime)) {
				tmp = 28;
			} else {
				tmp = 27;
			}
		} else {
			tmp = 30;
		}

		entityConversionTime.setMonthAllday(tmp);
		// 设置季度
		if (entityConversionTime.getMonthNUM() <= 3) {
			entityConversionTime.setFest(1);

		} else if (entityConversionTime.getMonthNUM() <= 6) {
			entityConversionTime.setFest(2);
		} else if (entityConversionTime.getMonthNUM() <= 9) {
			entityConversionTime.setFest(3);
		} else if (entityConversionTime.getMonthNUM() <= 12) {
			entityConversionTime.setFest(4);
		}

//				+ entityConversionTime.getMonthAllday() + "  "
//				+ entityConversionTime.getMonthNUM() + "  "
//				+ entityConversionTime.getWeekNUM() + "  "
//				+ entityConversionTime.getYearNUM() + "  ");
		return entityConversionTime;
	}

	/**
	 * 判断是否为闰年 false = not leap
	 */
	private static boolean isLeapYear(EntityConversionTime conversionTime) {
		boolean ret;
		if (conversionTime.getYearNUM() / 4 == 0
				&& conversionTime.getYearNUM() / 100 != 0) {//

			ret = true;

		} else {
			ret = false;
		}
		return ret;
	}
}

  

记录几个问题:1.

yyyy-MM-dd HH:mm:ss 其中HH 表示24小时制 hh表示12小时制

				
时间: 2024-12-11 10:08:30

Android 尺子效果,根据时间支持左右滑动(原创)的相关文章

Android :ViewPager+Fragment 实现顶部导航滑动效果

我还不会gif 所以连图表动态 可以滑动的 仔细看底下有滑动条的这是寒假做的一个APP的基本框架 将真啊 虽然效果都做出来了可是学长给了源码啊 所以最近做第二遍!!希望每一个控件都可以实现啊 下面是viewpager+fragment的效果 同样我们先写布局文件 思路就是一个Viewpager适配了五个fragment 底下的选择框是RadioGroup 里面有五个radiobutton activity_main里面就是由这些部分组成的的 代码如下 activity_main: <Linear

Android UI效果实现——滑动模糊渐变效果实现

前言: 大家应该都看到过iOS7解锁屏幕的滑动模糊渐变效果,好了,现在可以把手纸收起来了,今天黄老师就给大家讲一下如何在Android平台上 实现类似的滑动模糊渐变效果,其实方式远比你想像的简单. 目标效果展示: 第一部分:几个前提 说到模糊效果,我们先要了解几个前提 1.原图,指需要被模糊的一张位图 2.模糊,通常是采用指将一个位图的每个像素RGB值都取周围像素的RGB值的平均值,这样就可以产生模糊效果,一般通过高斯函数来实现, 至于Java中的实现方式黄老师就不给大家细讲了,我也不是搞图形算

Android实现渐显按钮的左右滑动效果

本示例演示在Android中实现带渐显按钮的左右滑动效果. 关于滑动效果,在我的上一篇博文中提到过,有兴趣的朋友可以访问: http://www.cnblogs.com/hanyonglu/archive/2012/02/13/2349827.html 如果大家想实现带指引效果的左右滑动,请访问博文:http://www.cnblogs.com/hanyonglu/archive/2012/04/07/2435589.html 先看下运行效果:    程序结构: MainActivity文件中代

Android 手势检测实战 打造支持缩放平移的图片预览效果(下)

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39480503,本文出自:[张鸿洋的博客] 上一篇已经带大家实现了自由的放大缩小图片,简单介绍了下Matrix:具体请参考:Android 手势检测实战 打造支持缩放平移的图片预览效果(上):本篇继续完善我们的ImageView~~ 首先加入放大后的移动~~ 1.自由的进行移动 我们在onTouchEvent里面,加上移动的代码,当然了,必须长或宽大于屏幕才可以移动~~~ @Ov

Android UI效果实现——Activity滑动退出效果

更新说明: 1.在QQ网友北京-旭的提醒下,在SlideFrame的initilize方法中添加了focusable.focusableInTouch.clickable的状态设置,否则会导致部分情况下无法滑动,感谢! 一.使用说明 使用方法很简单,只有一个类HorizontalActivity,继承自FragmentActivity类,实现了contentView的滑动事件触发和动画效果,要在自己的代码里实现,方法两种: 1.如果对Activity没特殊要求,直接继承HorizontalAct

Android可伸缩布局-FlexboxLayout(支持RecyclerView集成)

Android可伸缩布局-FlexboxLayout(支持RecyclerView集成) 1 . 前言 前几天看到Google官方的博客介绍了Google开源的一个强大的布局-FlexboxLayout,看见第一眼我心里的想法是,卧槽,Android 居然有这么一个强大的布局.作为一个有好奇心的工程狮,当然第一时间就去试了试手,效果非常赞,因此这篇文章就介绍一下它的用法和最新版添加的一些特性(支持集成RecyclerView),Github地址:https://github.com/google

Android的Activity屏幕切换动画-左右滑动切换

. --> 在Android开发过程中,经常会碰到Activity之间的切换效果的问题,下面介绍一下如何实现左右滑动的切换效果,首先了解一下Activity切换的实现,从Android2.0开始在Activity增加了一个方法: public void overridePendingTransition (int enterAnim, int exitAnim) 其中: enterAnim 定义Activity进入屏幕时的动画 exitAnim 定义Activity退出屏幕时的动画 overri

Android之fragment点击切换和滑动切换结合

学了一小段时间的Android,主要接触的是UI设计,打交道最多莫过于fragment了吧.在Android3.0引入了fragment的概念后,几乎在所以的Android的应用中都可以看见其身影,已经有很多前辈高人都已经详细介绍过fragmrnt,我这里就不多说什么了. 这里本来是想模仿一下微信的切换效果,怎奈水平不足,这里就献丑贴出半成品的代码,希望有大神能指点一下.废话不多说,上代码.先从简单的开始吧,这里是我一共用了3个fragment,这里就只贴出第一个的fragment的布局,别的两

[Android UI]可自动切换、无限滑动的图片广告展示栏的实现分享(续1)

本文非技术类文章,博主只是想分享这样的一种实现方法,帮助有需要的开发人员减少工作量.我是学java出身的,做开发2年了,很理解一句话:工欲善其事必先利其器. 继另一篇博文:[Android初级]可自动切换.无限滑动的广告栏的实现  ,我觉得还有更好的方式来展示,这个比较合适更多开发人员. 本次实现的demo,用到了第三方的开源框架:1.JazzyViewPager https://github.com/jfeinstein10/JazzyViewPager(主要用它,效果比较多) 2.unive