`

android开发旋转罗盘、风车

 
阅读更多

一、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 随手指旋转图片.zip

    【Android高级应用源码——Android之旋转罗盘与风车开发】 在Android应用程序开发中,实现复杂的动画效果,如旋转罗盘或风车,往往能提升用户体验,为用户带来更生动、更具交互性的界面。这份源码提供了一个示例,...

    安卓图片轮播广告轮播自动滚屏相关-android之旋转罗盘风车开发Android随手指旋转图片.rar

    【标题】"安卓图片轮播广告轮播自动滚屏相关-android之旋转罗盘风车开发Android随手指旋转图片.rar" 涉及的核心技术主要集中在Android应用开发领域,特别是图片展示与用户交互方面。这个项目的目标是实现一个具有...

    源码 图片轮播 android 之旋转罗盘 风车 开发 Android 随手指旋转图片.zip

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,...

    android之旋转罗盘风车开发

    旋转期间手指扳动罗盘,能加速罗盘旋转c.当罗盘在旋转的时候,手指按住罗盘,它会有刹车的效果。效果截图:为了形象点我用了一张风车的图作为例子技术要点1.需要扩展一个view,重写ondraw(),onTouchEvent(),onMeasure...

    android 指针转动的电子罗盘

    在Android开发中,电子罗盘是一个非常重要的组件,特别是在实现导航功能时。它能提供设备当前的磁北方向,帮助用户了解自身朝向。本文将深入探讨如何在Android平台上实现一个指针转动的电子罗盘。 首先,我们需要...

    旋转罗盘风车游戏案例

    在这款名为“旋转罗盘风车游戏”的案例中,开发者为我们提供了一个独特的Android游戏开发示例,它展示了如何创建一个互动式的罗盘风车应用程序。这个案例对于那些想要深入学习Android游戏开发,尤其是对交互设计感...

    iOS 旋转罗盘菜单

    在iOS应用开发中,"旋转罗盘菜单"是一种独特且吸引用户的交互设计,它通常用于展示一系列可选项,用户可以通过旋转模拟罗盘的方式来选择。这种菜单设计为用户提供了一种直观且有趣的交互方式,尤其适用于设置界面...

    android的罗盘应用

    在Android开发领域,创建一个罗盘应用是一项有趣的挑战,它涉及到对硬件传感器的利用和图形渲染技术的应用。本文将深入探讨如何在Android Studio上利用OpenGL ES加载罗盘图片,并根据手机的转动角度来实现罗盘的动态...

    Android实现电子罗盘(指南针)方向传感器的应用

    Android 实现电子罗盘(指南针)方向传感器的应用 ... Android 实现电子罗盘方向传感器的应用是一种非常有趣和实用的技术,我们可以通过使用方向传感器来开发一些非常实用的应用,让用户更方便地了解自己的方向和位置。

    android 罗盘 源码

    在Android平台上开发一款精准且美观的罗盘应用,涉及到的核心技术主要包括传感器的使用、图形绘制以及用户界面设计。本文将详细解析"android 罗盘 源码"中的关键知识点,帮助你深入理解如何在Android系统上实现一个...

    Android自定义View 圆形刻度罗盘 仪表盘 指针动态改变

    在Android开发中,自定义View是一项重要的技能,它允许开发者创造出独特且富有表现力的UI元素,以满足特定的设计需求。本项目聚焦于一个特定的自定义View:圆形刻度罗盘,也就是我们通常所说的仪表盘。这个仪表盘...

    CSS3风水罗盘旋转动画特效.rar

    CSS3风水罗盘旋转动画特效.rar CSS3风水罗盘旋转动画特效.rar CSS3风水罗盘旋转动画特效.rar CSS3风水罗盘旋转动画特效.rar CSS3风水罗盘旋转动画特效.rar CSS3风水罗盘旋转动画特效.rar CSS3风水罗盘旋转动画特效....

    CSS3风水罗盘旋转特效无水印版

    【CSS3风水罗盘旋转特效无水印版】是一个基于CSS3技术实现的网页动态元素,主要用于呈现一种视觉效果——风水罗盘的旋转动画。这个特效的独特之处在于它模拟了真实罗盘的多层次结构,各个环层具有不同的旋转速度和...

    Android自定义罗盘视图

    通过本示例的学习,初学者可快速掌握自定义控件的开发技巧。本例是博文http://blog.csdn.net/l1028386804/article/details/47337949的完整代码,如想了解实现细节,请参考博文:...

    Qt程序罗盘设计,自动旋转

    在Qt编程环境中,创建一个能够自动旋转的罗盘是一个涉及图形用户界面(GUI)和动画效果的任务。Qt库提供了一套强大的工具,如QGraphicsView和QGraphicsScene,用于构建复杂的2D图形,并且QPropertyAnimation可以实现...

    基于Android平台飞机罗盘校准系统软件的实现.pdf

    【基于Android平台飞机罗盘校准系统软件的实现】 在现代航空领域,飞行安全与导航系统的准确性密切相关。其中,磁罗盘作为传统导航设备之一,其校准精度和效率直接影响到飞行安全。针对这一问题,本文提出了一种...

    android-pad 罗盘

    android pad版的指南针不多,这款是为数不多的我认为毕竟好的apk之一

    Android 简易罗盘

    在Android平台上,开发一个简易罗盘应用涉及到的关键技术主要包括Android的传感器API以及UI设计。本文将深入探讨如何利用这些技术来实现一个基本的指北针功能。 首先,我们需要理解Android中的传感器系统。Android...

Global site tag (gtag.js) - Google Analytics