原来朋友给过的一个 显示时间的 样例,还能够改动时间,可是要机子有root权限才干改动。

在这个时间表盘的样例基础上 改动改动  图片。背景图什么的      就能够达到自己想要的效果了。。

下载地址:  http://download.csdn.net/detail/kongbaidepao/8090083

1个风车效果的样例

是依据手滑动的速度 转动快慢的

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva29uZ2JhaWRlcGFv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

代码不多,直接粘过来

public class MainActivity extends Activity {

    @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RotatView rotatView=(RotatView)findViewById(R.id.myRotatView);
rotatView.setRotatDrawableResource(R.drawable.cycle);
} }
public class RotatView extends View {

    //原心坐标x
float o_x;
float o_y; /**
* 处理惯性的handler
*/
Handler handler;
//handler处理消息的间隔
int delayedTime = 20; /**
* 消息信号,滚动的标识
*/
static final int play = 0; /**
* 消息信号,停止滚动的标识
*/
static final int stop = 1; /**
* 上次记录的时间,计算一定时间所走过的弧度、计算速度.
*/
double currentTime = 0; /**
* 图片的宽度
*/
int width; /**
* 图片的高度
*/
int height; /**
* view的真实宽度与高度:由于是旋转。所以这个view是正方形,它的值是图片的对角线长度
*/
double maxwidth; /**
* 旋转的图片
*/
Bitmap rotatBitmap; public RotatView(Context context, AttributeSet attrs) {
super(context, attrs);
init(); } /**
* 初始化handler与速度计算器
*/
private void init() {
vRecord = new VRecord();
handler = new Handler() { @Override
public void handleMessage(Message msg) { double detaTime = System.currentTimeMillis() - currentTime;
switch (msg.what) { case play: {
if (isClockWise) {
speed = speed - a * detaTime;
if (speed <= 0) {
return;
} else {
handler.sendEmptyMessageDelayed(play, delayedTime);
}
} else {
speed = speed + a * detaTime;
if (speed >= 0) {
return;
} else {
handler.sendEmptyMessageDelayed(play, delayedTime);
}
} addDegree((float)(speed * detaTime + (a * detaTime * detaTime) / 2)); // if (a < a_max) {
// a = (float)(a + a_add*detaTime);
// System.out.println("a:"+a);
// }
currentTime = System.currentTimeMillis();
invalidate(); break;
}
case stop: {
speed = 0;
handler.removeMessages(play);
}
} super.handleMessage(msg);
}
};
// 默认是有一张图片的 initSize();
} public void setRotatBitmap(Bitmap bitmap) {
rotatBitmap = bitmap;
initSize();
postInvalidate();
} public void setRotatDrawableResource(int id) { BitmapDrawable drawable = (BitmapDrawable)getContext().getResources().getDrawable(id); setRotatDrawable(drawable);
} public void setRotatDrawable(BitmapDrawable drawable) {
rotatBitmap = drawable.getBitmap();
initSize();
postInvalidate();
} private void initSize() {
if (rotatBitmap == null) { // throw new NoBitMapError("Error,No bitmap in RotatView!");
return;
}
width = rotatBitmap.getWidth();
height = rotatBitmap.getHeight(); maxwidth = Math.sqrt(width * width + height * height); o_x = o_y = (float)(maxwidth / 2);//确定圆心坐标
} /**
* 通过此方法来控制旋转度数,假设超过360,让它求余,防止,该值过大造成越界
*
* @param added
*/
private void addDegree(float added) {
deta_degree += added;
if (deta_degree > 360 || deta_degree < -360) {
deta_degree = deta_degree % 360;
} } @Override
protected void onDraw(Canvas canvas) { Matrix matrix = new Matrix();
// 设置转轴位置
matrix.setTranslate((float)width / 2, (float)height / 2); // 開始转
matrix.preRotate(deta_degree);
// 转轴还原
matrix.preTranslate(-(float)width / 2, -(float)height / 2); // 将位置送到view的中心
matrix.postTranslate((float)(maxwidth - width) / 2, (float)(maxwidth - height) / 2); canvas.drawBitmap(rotatBitmap, matrix,paint); super.onDraw(canvas);
} Paint paint=new Paint();
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 它的宽高不是图片的宽高,而是以宽高为直角的矩形的对角线的长度
setMeasuredDimension((int)maxwidth, (int)maxwidth); } /**
* 手指触屏的初始x的坐标
*/
float down_x; /**
* 手指触屏的初始y的坐标
*/
float down_y; /**
* 移动时的x的坐标
*/
float target_x; /**
* 移动时的y的坐标
*/
float target_y; /**
* 放手时的x的坐标
*/
float up_x; /**
* 放手时的y的坐标
*/
float up_y; /**
* 当前的弧度(以该 view 的中心为圆点)
*/
float current_degree; /**
* 放手时的弧度(以该 view 的中心为圆点)
*/
float up_degree; /**
* 当前圆盘所转的弧度(以该 view 的中心为圆点)
*/
float deta_degree; /**
* 最后一次手势滑过的时间
*/
double lastMoveTime = 0; /**
* 最小加速度(当手指放手是)
*/
public static final float a_min = 0.001f; /**
* 加速度增量
*/
public static final float a_add = 0.001f; /**
* 加速度
*/
float a = a_min; /**
* 最大加速度(当手指按住时)
*/
public static final float a_max = a_min * 5; /**
* 旋转速度(度/毫秒)
*/
double speed = 0; /**
* 速度计算器
*/
VRecord vRecord; /**
* 是否为顺时针旋转
*/
boolean isClockWise; @Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
if (rotatBitmap == null) { throw new NoBitMapError("Error,No bitmap in RotatView!");
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
down_x = event.getX();
down_y = event.getY();
current_degree = detaDegree(o_x, o_y, down_x, down_y);
vRecord.reset();
// handler.sendEmptyMessage(stop);
a = a_max; break; }
case MotionEvent.ACTION_MOVE: {
down_x = target_x = event.getX();
down_y = target_y = event.getY();
float degree = detaDegree(o_x, o_y, target_x, target_y); // 滑过的弧度增量
float dete = degree - current_degree;
// 假设小于-90度说明 它跨周了,须要特殊处理350->17,
if (dete < -270) {
dete = dete + 360; // 假设大于90度说明 它跨周了,须要特殊处理-350->-17,
} else if (dete > 270) {
dete = dete - 360;
}
lastMoveTime = System.currentTimeMillis();
vRecord.add(dete, lastMoveTime);
addDegree(dete);
current_degree = degree;
postInvalidate(); break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
a = a_min; double lastupTime = System.currentTimeMillis();
double detaTime = lastupTime - lastMoveTime;
up_x = event.getX();
up_y = event.getY();
up_degree = detaDegree(o_x, o_y, up_x, up_y);
// 放手时的速度
speed = speed + vRecord.getSpeed();
if (speed > 0) {
speed = Math.min(VRecord.max_speed, speed);
} else {
speed = Math.max(-VRecord.max_speed, speed);
}
// System.out.println("speed:" + speed);
if (speed > 0) {
isClockWise = true;
// v = 1;
} else {
isClockWise = false;
// v = -1;
}
currentTime = System.currentTimeMillis();
handler.sendEmptyMessage(0);
break;
}
}
return true;
} /**
* 计算以(src_x,src_y)为坐标圆点,建立直角体系,求出(target_x,target_y)坐标与x轴的夹角
* 主要是利用反正切函数的知识求出夹角
*
* @param src_x
* @param src_y
* @param target_x
* @param target_y
* @return
*/
float detaDegree(float src_x, float src_y, float target_x, float target_y) { float detaX = target_x - src_x;
float detaY = target_y - src_y;
double d;
if (detaX != 0) {
float tan = Math.abs(detaY / detaX); if (detaX > 0) { if (detaY >= 0) {
d = Math.atan(tan); } else {
d = 2 * Math.PI - Math.atan(tan);
} } else {
if (detaY >= 0) { d = Math.PI - Math.atan(tan);
} else {
d = Math.PI + Math.atan(tan);
}
} } else {
if (detaY > 0) {
d = Math.PI / 2;
} else { d = -Math.PI / 2;
}
} return (float)((d * 180) / Math.PI);
} /**
* 一个异常。用来推断是否有rotatbitmap
*
* @author sun.shine
*/
static class NoBitMapError extends RuntimeException { /**
*
*/
private static final long serialVersionUID = 1L; public NoBitMapError(String detailMessage) {
super(detailMessage);
} } /**
* 速度计算器 原来是将近期的 弧度增量和时间点记录下来,然后<br>
* 通过增量除以总时间求出平均值做为它的即时手势滑过的速度
*
* @author sun.shine
*/
static class VRecord { /**
* 数组中的有效数字
*/
int addCount; /**
* 最大能装的数据空间
*/
public static final int length = 15; /**
* 二维数组,1.保存弧度增量.2.保存产生这个增量的时间点
*/
double[][] record = new double[length][2]; /**
* 为二维数组装载数据<br>
* 注:通过此方法,有个特点,能把最后的length组数据记录下来,length以外的会丢失
*
* @param detadegree
* @param time
*/
public void add(double detadegree, double time) { for (int i = length - 1; i > 0; i--) {
record[i][0] = record[i - 1][0];
record[i][1] = record[i - 1][1];
}
record[0][0] = detadegree;
record[0][1] = time;
addCount++; } /**
* 最大速度
*/
public static final double max_speed = 8; /**
* 通过数组里所装载的数据分析出即时速度<br>
* 原理是:计算数组里的时间长度和增量的总数。然后求出每毫秒所走过的弧度<br>
* 当然不能超过{@link VRecord#max_speed}
*
* @return
*/
public double getSpeed() { if (addCount == 0) {
return 0;
}
int maxIndex = Math.min(addCount, length) - 1; if ((record[0][1] - record[maxIndex][1]) == 0) {
return 0;
} double detaTime = record[0][1] - record[maxIndex][1];
double sumdegree = 0;
for (int i = 0; i < length - 1; i++) { sumdegree += record[i][0];
// System.out.println(record[i][0]);
} // System.out.println("----------");
// System.out.println(sumdegree);
// System.out.println(detaTime);
double result = sumdegree / detaTime;
if (result > 0) {
return Math.min(result, max_speed);
} else {
return Math.max(result, -max_speed);
}
// System.out.println("v=" + result); } /**
* 重置
*/
public void reset() {
addCount = 0;
for (int i = length - 1; i > 0; i--) {
record[i][0] = 0;
record[i][1] = 0;
}
}
} @Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if(rotatBitmap!=null){
rotatBitmap.recycle();
rotatBitmap=null;
}
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffffff" > <com.sun.shine.myrotation.view.RotatView
android:id="@+id/myRotatView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dip" >
</com.sun.shine.myrotation.view.RotatView> </RelativeLayout>

最新文章

  1. 『.NET Core CLI工具文档』(十三)dotnet-publish
  2. shell 脚本之 shell 练习题汇总
  3. javascript实现优先队列
  4. chrome shortcutkey
  5. 电脑没有关机可能出现发博文dns异常(write)
  6. paip.java c++得到当前类,方法名称以及行号
  7. 代码生成器Kalman Studio2.2发布,完美支持Oracle,不需要安装Oracle客户端
  8. UESTC 912 树上的距离 --LCA+RMQ+树状数组
  9. 解释一下,在你往浏览器中输入一个URL后都发生了什么,要尽可能详细
  10. 汇编语言(学习笔记-----[bx]和loop)
  11. html5 css3 如何绘制扇形任意角度
  12. 用jq 做了一个排序
  13. 学习javascript基础知识系列第二节 - this用法
  14. python 正则表达式汇总
  15. CocoaChina(总结)升级到xcode8遇到的问题及解决方案
  16. 你不知道的JavaScript--Item26 异步的脚本加载
  17. kibana从入门到精通-Kibana安装
  18. [PHP]PHP rpc框架hprose测试
  19. python入门科普IDE工具和编译环境
  20. Code Forces 652A Gabriel and Caterpillar

热门文章

  1. 分布式文件存储FastDFS(七)FastDFS配置文件具体解释
  2. linux的子进程调用exec( )系列函数
  3. MFC画图总结-DIB图形绘制
  4. nodejs检查已安装模块
  5. Platinum UPnP
  6. window下redis nosql初试
  7. $watch
  8. 机器学习笔记(十)EM算法及实践(以混合高斯模型(GMM)为例来次完整的EM)
  9. 〖Linux〗Ubuntu13.10中打开键盘背光灯
  10. 数制转换-栈的应用(C++实现)