一、RotatView
package com.sun.shine.myrotation.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.drawable.BitmapDrawable; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.SurfaceView; import android.view.View; public class RotatView extends View { float o_x; float o_y; Handler handler; int delayedTime = 20; static final int play = 0; static final int stop = 1; double currentTime = 0; int width; int height; double maxwidth; Bitmap rotatBitmap; public RotatView(Context context, AttributeSet attrs) { super(context, attrs); init(); } 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);// ȷ��Բ����� } 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); 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); } float down_x; float down_y; float target_x; float target_y; float up_x; float up_y; float current_degree; float up_degree; 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; if (dete < -270) { dete = dete + 360; } 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; } 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); } static class NoBitMapError extends RuntimeException { /** * */ private static final long serialVersionUID = 1L; public NoBitMapError(String detailMessage) { super(detailMessage); } } static class VRecord { int addCount; public static final int length = 15; double[][] record = new double[length][2]; 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; 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; } } }
二、MainActivity
package com.sun.shine.myrotation; import com.sun.shine.myrotation.view.RotatView; import android.os.Bundle; import android.app.Activity; 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); } }
相关推荐
【Android高级应用源码——Android之旋转罗盘与风车开发】 在Android应用程序开发中,实现复杂的动画效果,如旋转罗盘或风车,往往能提升用户体验,为用户带来更生动、更具交互性的界面。这份源码提供了一个示例,...
【标题】"安卓图片轮播广告轮播自动滚屏相关-android之旋转罗盘风车开发Android随手指旋转图片.rar" 涉及的核心技术主要集中在Android应用开发领域,特别是图片展示与用户交互方面。这个项目的目标是实现一个具有...
免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,...
旋转期间手指扳动罗盘,能加速罗盘旋转c.当罗盘在旋转的时候,手指按住罗盘,它会有刹车的效果。效果截图:为了形象点我用了一张风车的图作为例子技术要点1.需要扩展一个view,重写ondraw(),onTouchEvent(),onMeasure...
在Android开发中,电子罗盘是一个非常重要的组件,特别是在实现导航功能时。它能提供设备当前的磁北方向,帮助用户了解自身朝向。本文将深入探讨如何在Android平台上实现一个指针转动的电子罗盘。 首先,我们需要...
在这款名为“旋转罗盘风车游戏”的案例中,开发者为我们提供了一个独特的Android游戏开发示例,它展示了如何创建一个互动式的罗盘风车应用程序。这个案例对于那些想要深入学习Android游戏开发,尤其是对交互设计感...
在iOS应用开发中,"旋转罗盘菜单"是一种独特且吸引用户的交互设计,它通常用于展示一系列可选项,用户可以通过旋转模拟罗盘的方式来选择。这种菜单设计为用户提供了一种直观且有趣的交互方式,尤其适用于设置界面...
Android 实现电子罗盘(指南针)方向传感器的应用 ... Android 实现电子罗盘方向传感器的应用是一种非常有趣和实用的技术,我们可以通过使用方向传感器来开发一些非常实用的应用,让用户更方便地了解自己的方向和位置。
在Android开发领域,创建一个罗盘应用是一项有趣的挑战,它涉及到对硬件传感器的利用和图形渲染技术的应用。本文将深入探讨如何在Android Studio上利用OpenGL ES加载罗盘图片,并根据手机的转动角度来实现罗盘的动态...
CSS3风水罗盘旋转动画特效.rar CSS3风水罗盘旋转动画特效.rar CSS3风水罗盘旋转动画特效.rar CSS3风水罗盘旋转动画特效.rar CSS3风水罗盘旋转动画特效.rar CSS3风水罗盘旋转动画特效.rar CSS3风水罗盘旋转动画特效....
在Android开发中,自定义View是一项重要的技能,它允许开发者创造出独特且富有表现力的UI元素,以满足特定的设计需求。本项目聚焦于一个特定的自定义View:圆形刻度罗盘,也就是我们通常所说的仪表盘。这个仪表盘...
在Android平台上开发一款精准且美观的罗盘应用,涉及到的核心技术主要包括传感器的使用、图形绘制以及用户界面设计。本文将详细解析"android 罗盘 源码"中的关键知识点,帮助你深入理解如何在Android系统上实现一个...
【CSS3风水罗盘旋转特效无水印版】是一个基于CSS3技术实现的网页动态元素,主要用于呈现一种视觉效果——风水罗盘的旋转动画。这个特效的独特之处在于它模拟了真实罗盘的多层次结构,各个环层具有不同的旋转速度和...
通过本示例的学习,初学者可快速掌握自定义控件的开发技巧。本例是博文http://blog.csdn.net/l1028386804/article/details/47337949的完整代码,如想了解实现细节,请参考博文:...
在Qt编程环境中,创建一个能够自动旋转的罗盘是一个涉及图形用户界面(GUI)和动画效果的任务。Qt库提供了一套强大的工具,如QGraphicsView和QGraphicsScene,用于构建复杂的2D图形,并且QPropertyAnimation可以实现...
android pad版的指南针不多,这款是为数不多的我认为毕竟好的apk之一
在Android平台上,开发一个简易罗盘应用涉及到的关键技术主要包括Android的传感器API以及UI设计。本文将深入探讨如何利用这些技术来实现一个基本的指北针功能。 首先,我们需要理解Android中的传感器系统。Android...
本文将介绍一款创新的基于Android系统的飞机罗盘校准系统软件,该软件的开发旨在提高校准过程的精度和效率。 该系统软件主要由三个模块构成:座舱显控单元、牵引车显控单元和基准罗盘单元。三个模块通过WiFi无线...