Android 360度摇杆

新建一个类。举例为MySurfaceView

package com.example.blt;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;

public class MySurfaceView extends SurfaceView implements Callback {

	private SurfaceHolder sfh;
	private Canvas canvas;
	private Paint paint;
	private int coordinate;
	// 固定摇杆背景圆形的半径
	private int RockerCircleR, SmallRockerCircleR;
	// 摇杆的X,Y坐标以及摇杆的半径
	private float SmallRockerCircleX, SmallRockerCircleY;

	private RudderListener listener = null; // 事件回调接口

	public MySurfaceView(Context context) {
		super(context);
	}

	public MySurfaceView(Context context, AttributeSet as) {
		super(context, as);
		this.setKeepScreenOn(true);
		sfh = getHolder();
		sfh.addCallback(this);
		paint = new Paint();
		paint.setColor(Color.GREEN);
		paint.setAntiAlias(true);// 抗锯齿
		setFocusable(true);
		setFocusableInTouchMode(true);
		setZOrderOnTop(true);
		sfh.setFormat(PixelFormat.TRANSPARENT);// 设置背景透明

	}

	public void surfaceCreated(SurfaceHolder holder) {

		// 获得控件最小值
		int little = this.getWidth() < this.getHeight() ? this.getWidth()
				: this.getHeight();
		// 根据屏幕大小绘制
		SmallRockerCircleX = SmallRockerCircleY = coordinate = little / 2;
		// 固定摇杆背景圆形的半径
		RockerCircleR = (int) (little * 0.35);
		// 摇杆的半径
		SmallRockerCircleR = (int) (little * 0.15);

		draw();
	}

	/***
	 * 得到两点之间的弧度
	 */
	public double getRad(float px1, float py1, float px2, float py2) {
		// 得到两点X的距离
		float x = px2 - px1;
		// 得到两点Y的距离
		float y = py1 - py2;
		// 算出斜边长
		float xie = (float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
		// 得到这个角度的余弦值(通过三角函数中的定理 :邻边/斜边=角度余弦值)
		float cosAngle = x / xie;
		// 通过反余弦定理获取到其角度的弧度
		float rad = (float) Math.acos(cosAngle);
		// 注意:当触屏的位置Y坐标<摇杆的Y坐标我们要取反值-0~-180
		if (py2 < py1) {
			rad = -rad;
		}
		return rad;
	}

	@SuppressLint("ClickableViewAccessibility")
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_DOWN
				|| event.getAction() == MotionEvent.ACTION_MOVE) {
			// 当触屏区域不在活动范围内
			if (Math.sqrt(Math.pow((coordinate - (int) event.getX()), 2)
					+ Math.pow((coordinate - (int) event.getY()), 2)) >= RockerCircleR) {
				// 得到摇杆与触屏点所形成的角度
				double tempRad = getRad(coordinate, coordinate, event.getX(),
						event.getY());
				// 保证内部小圆运动的长度限制
				getXY(coordinate, coordinate, RockerCircleR, tempRad);
			} else {// 如果小球中心点小于活动区域则随着用户触屏点移动即可
				SmallRockerCircleX = (int) event.getX();
				SmallRockerCircleY = (int) event.getY();
			}
		} else if (event.getAction() == MotionEvent.ACTION_UP) {
			// 当释放按键时摇杆要恢复摇杆的位置为初始位置
			SmallRockerCircleX = coordinate;
			SmallRockerCircleY = coordinate;
		}
		draw();
		if (listener != null) {
			listener.onSteeringWheelChanged((SmallRockerCircleX - coordinate)
					/ RockerCircleR, (coordinate - SmallRockerCircleY)
					/ RockerCircleR);
		}
		return true;
	}

	/**
	 * 
	 * @param R
	 *            圆周运动的旋转点
	 * @param centerX
	 *            旋转点X
	 * @param centerY
	 *            旋转点Y
	 * @param rad
	 *            旋转的弧度
	 */
	public void getXY(float centerX, float centerY, float R, double rad) {
		// 获取圆周运动的X坐标
		SmallRockerCircleX = (float) (R * Math.cos(rad)) + centerX;
		// 获取圆周运动的Y坐标
		SmallRockerCircleY = (float) (R * Math.sin(rad)) + centerY;
	}

	public void draw() {
		try {
			canvas = sfh.lockCanvas();
			// canvas.drawColor(Color.WHITE);
			canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);// 清除屏幕
			// 设置透明度
			paint.setColor(Color.CYAN);
			// 绘制摇杆背景
			canvas.drawCircle(coordinate, coordinate, RockerCircleR, paint);
			paint.setColor(Color.RED);
			// 绘制摇杆
			canvas.drawCircle(SmallRockerCircleX, SmallRockerCircleY,
					SmallRockerCircleR, paint);
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			try {
				if (canvas != null)
					sfh.unlockCanvasAndPost(canvas);
			} catch (Exception e2) {

			}
		}
	}

	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
	}

	// 设置回调接口
	public void setRudderListener(RudderListener rockerListener) {
		listener = rockerListener;
	}

	// 回调接口
	public interface RudderListener {
		void onSteeringWheelChanged(float cross, float longitudinal);
	}
}

主窗体中

package com.example.blt;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class ControlActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.activity_control);
		MySurfaceView temp = (MySurfaceView) findViewById(R.id.rudder);
		temp.setRudderListener(new MySurfaceView.RudderListener() {

			@Override
			public void onSteeringWheelChanged(float cross, float longitudinal) {
				// TODO Auto-generated method stub
				Log.v("change", "c" + cross + "l" + longitudinal);
				((TextView) findViewById(R.id.textView2)).setText("c:" + cross
						+ "l:" + longitudinal);
			}
		});
		((Button) findViewById(R.id.button2))
				.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						// TODO Auto-generated method stub

					}
				});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		// getMenuInflater().inflate(R.menu.control, menu);
		return false;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}

----------------------主窗体XML

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin" >

    <GridLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:columnCount="3" >

        <com.example.blt.MySurfaceView
            android:id="@+id/rudder"
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:layout_column="0"
            android:layout_gravity="left|bottom" />

        <TextView
            android:id="@+id/textView2"
            android:layout_column="1"
            android:layout_gravity="left|top"
            android:text="TextView" />

        <TableLayout
            android:layout_column="2"
            android:layout_gravity="bottom"
            android:layout_row="0" >

            <TableRow
                android:id="@+id/tableRow1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" >

                <TextView
                    android:id="@+id/axis_x"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="TextView" />
            </TableRow>

            <TableRow
                android:id="@+id/tableRow2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" >

                <Button
                    android:id="@+id/button2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="自动" />

                <Button
                    android:id="@+id/button3"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Button" />
            </TableRow>

            <TableRow
                android:id="@+id/tableRow3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" >

                <Button
                    android:id="@+id/button1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Button" />

                <Button
                    android:id="@+id/button4"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Button" />
            </TableRow>

            <TableRow
                android:id="@+id/tableRow4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" >

                <Button
                    android:id="@+id/button5"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Button" />

                <Button
                    android:id="@+id/button6"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Button" />
            </TableRow>
        </TableLayout>
    </GridLayout>

</RelativeLayout>

------------------------------应用到自定义控件

时间: 2024-08-05 22:35:24

Android 360度摇杆的相关文章

怎么样拍摄360度全景?

360全景不是凭空生成的,要制作一个360全景,我们需要有原始的图像素材,原始图像素材的来源可以是: A.在现实的场景中,使用相机的全景拍摄功能得到的鱼眼图像 B.通过建模渲染得到的虚拟图像 下文中的表格对比了在不同的设备.拍摄机位.拼合模式.拍摄难度下所能获得到的鱼眼图像 要拍摄全景素材我们需要用到一些专业设备,如下: 数码单反相机 360全景拍摄硬件配备-数码单反相机 首先让我们来认识一下什么是数码单反相机.说白了,数码单反相机就是使用了单反新技术的数码相机.作为专业级的数码相机,用其拍摄出

政府展示360全景应用,虚拟馆360度展示解决方案

政府需求分析: 1.数字城市.360全景城市风采展示 2.园区规划,招商引资,打造城市和产业园区的电子名片 3.大力发展在线城市管理体系:城市应急系统.城管.消防.安全等电子系统 4.大型经济和文化招商会.博览会.运动会宣传展示 5.非物质文化遗产宣传展示 6.名胜古迹宣传展示,打造低碳绿色旅游产业 360全景的特点: 1.水平垂直各360全景,一共360度视角,没有任何视线盲点,想看哪里就看哪儿; 2.全部是实景拍摄,真实立体; 3.高清晰度,采用专业自改制高像素相机; 4.互动性强,鼠标随意

360度评价反馈有哪些使用场景?

作为支持组织管理及领导力发展的工具,360度评估反馈是组织人才管理战略的重要组成部分.它能够评估员工的优缺点,并作为培训或教练计划的出发点.因为360度评估反馈具有全面性,所以它能够有效区分出那些表现优秀的员工.刚刚符合期望的员工以及亟待发展的员工.当然,这些评估结果远不止帮助企业创造利润,影响员工的评定.培养以及留任:更能在员工的关键行为.能力和工作标准间建立一致性.从人才管理的业务出发,360度评估反馈在人才管理的多个方面发挥作用. 发展领导力360度评估反馈法在领导力发展的整个生命周期中有

虚幻UE4中如何采集360度全景图片和VR视频

如何使用虚幻4来制作一个VR视频播放器呢,简单来讲,使用虚幻4的视频采集插件来获取图像,并对图像进行处理,就能获取我们需要的图像了,下一步,你可以把图像投影到一个360度球体上,就能形成球形的播放器了. 1.插件测试-采集单帧双眼图像 打开Epic Games Launcher,启动引擎(我使用的版本为4.14.0).在弹出的对话框中点击New Project标签栏,再选择C++标签页,选择Vehicle Advanced模板,并将项目命名为STEREOSCOPIC.最后点击CreateProj

360度 图片 旋转

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <title>CSS3鼠标悬停360度旋转效果 </title> <style> * { margin:0; padding:0; list-style:none; } body { background:#1F1F1F; } .zzsc { width

Android流畅度测试

Android流畅度测试 测试方法一:系统自带-开发者模式 测试方法二:FPS Meter测试安卓帧数 H5页面加载速度:window.performance.timing 测试方法一:系统自带-开发者模式 实际上,为了方便开发者测试,安卓本身就内置了流畅度检测的功能.不过,这需要我们开启隐藏的开发者选项.如果你在用原生系统,那么开启开发者选项的方法很简单,进入到设置菜单“关于手机”页面,点击数次“版本号”,即可开启开发者选项.如果用的是其他ROM,方法也许有所不同,比如说魅族的Flyme开启开

企业遇到什么问题有必要做360度评估?

许多人力资源从业者在推动360度评估项目是,希望能够找到一些更为量化的评估角度来考察360度项目推进的时机.可以试着参考以下指标,如果有三项以上符合你所在的组织的情况,就应该考虑是否引入360度评估反馈技术,以及该如何设计和实施360度评估反馈技术. 一年内出现过新晋管理者不够胜利,“提拔错了人”的情况: 管理者与员工之间.管理者之间关系紧张,频繁发生冲突: 管理者对提升自我并无动力,被动学习: 管理者成熟度偏低.长期无改善: 管理者不知道如何发展: 高潜员工抱怨企业对他们的关注不足: 培训需求

[JavaScript案例]360度全景照片

案例: 360度全景照片 鼠标在页面上滑动时图片表现的物体会随着移动方向进行旋转,从而呈现360度物体旋转效果 思路: 将所有的图片都放入指定容器内,通过切换相应的照片隐藏与显示来实现旋转效果 代码: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta id="viewport" name="

html5人物图片360度立体旋转

体验效果:http://hovertree.com/texiao/html5/10.htm 下载:http://hovertree.com/hvtart/bjae/t16oddyt.htm 代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Full 360 degree View - HoverTree</title> <sty