Android手机摇杆
1,在Activity中,只要在oncreat方法进行如下定义
public class BallActivity extends Activity{
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_ball);Rudder rud = (Rudder)findViewById(R.id.rudder);rud.setRudderListener(new RudderListener() {public void onSteeringWheelChanged(int action, int angle) {if(action == Rudder.ACTION_RUDDER) {//TODO:事件实现}}});}
2,类Rudder继承SurfaceView和实现Runnable, Callback接口,具体如下:
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PorterDuff.Mode;
import android.graphics.RectF;
import android.view.SurfaceHolder.Callback;
import android.support.v4.app.NotificationCompat.Action;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class Rudder extends SurfaceView implements Runnable, Callback {
public static final int ACTION_RUDDER = 1, ACTION_ATTACK = 2; // 1:摇杆事件// private ArrayList<Ball> list = new ArrayList<Ball>(); //// 2:按钮事件(未实现)private SurfaceHolder MyHolder;private boolean isStop = false;private Thread MyThread;private Paint MyPaint;private Point MyRockerPosition; // 摇杆位置private Point MyBallPosition;private Point MyCtrlPoint = new Point(200, 800);// 摇杆起始位置private RudderListener listener = null; // 事件回调接口private Canvas canvas = null;private Paint paint = new Paint();private Ball ball;private int MyRudderRadius = 40;// 摇杆半径private int MyBallRadius = 70; // 小球半径private int MyWheelRadius = 120;// 摇杆活动范围半径private int x, x2, y, y2, x3, y3;public Rudder(Context context) {super(context);// TODO Auto-generated constructor stub}public Rudder(Context context, AttributeSet as) {super(context, as);this.setKeepScreenOn(true);MyHolder = getHolder();MyHolder.addCallback((android.view.SurfaceHolder.Callback) this);MyThread = new Thread(this);MyPaint.setColor(Color.CYAN); // 设置摇杆背景颜色MyPaint.setAntiAlias(true); // 抗锯齿MyRockerPosition = new Point(MyCtrlPoint);setFocusable(true);setFocusableInTouchMode(true);// setZOrderOnTop(true);MyHolder.setFormat(PixelFormat.TRANSLUCENT); // 设置背景透明}public void setRudderListener(RudderListener rockerListener) {listener = rockerListener;}public void run() {// TODO Auto-generated method stubwhile (!isStop) {try {canvas = MyHolder.lockCanvas();canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);// 清除屏幕MyPaint.setColor(Color.WHITE); // 设置背景
// RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
// canvas.drawRect(rect, paint);// ball=new// Ball((this.getWidth())/2,(this.getHeight())/2,80,Color.GREEN);// list.add(ball);//// for(int i=0;i<list.size();i++){// Ball ball2=list.get(i);// ball2.drawBall(paint, canvas);}MyPaint.setColor(Color.CYAN);canvas.drawCircle(MyCtrlPoint.x, MyCtrlPoint.y, MyWheelRadius,MyPaint);// 绘制范围MyPaint.setColor(Color.RED);canvas.drawCircle(MyRockerPosition.x, MyRockerPosition.y,MyRudderRadius, MyPaint);// 绘制摇杆// 绘制初始小球MyBallPosition = new Point((this.getWidth() / 2),this.getHeight() / 2);MyPaint.setColor(Color.GREEN);canvas.drawCircle(MyBallPosition.x, MyBallPosition.y,MyBallRadius, MyPaint);} catch (Exception e) {e.printStackTrace();} finally {if (canvas != null) {MyHolder.unlockCanvasAndPost(canvas);}}try {Thread.sleep(30);} catch (InterruptedException e) {e.printStackTrace();}}}public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}public void surfaceCreated(SurfaceHolder holder) {MyThread.start();}public void surfaceDestroyed(SurfaceHolder holder) {isStop = true;}public boolean onTouchEvent(MotionEvent event) {// Ball ball3=list.get(0);int length = MathSave.getLength(MyCtrlPoint.x, MyCtrlPoint.y,event.getX(), event.getY());
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// 如果屏幕接触点不在摇杆挥动范围内,则不处理if (length > MyWheelRadius) {return true;}}if (event.getAction() == MotionEvent.ACTION_MOVE) {if (length <= MyWheelRadius) {// 如果手指在摇杆活动范围内,则摇杆处于手指触摸位置MyRockerPosition.set((int) event.getX(), (int) event.getY());} else {// 设置摇杆位置,使其处于手指触摸方向的 摇杆活动范围边缘MyRockerPosition = MathSave.getBorderPoint(MyCtrlPoint,new Point((int) event.getX(), (int) event.getY()),MyWheelRadius);}if (listener != null) {float radian = MathSave.getRadian(MyCtrlPoint, new Point((int) event.getX(), (int) event.getY()));listener.onSteeringWheelChanged(ACTION_RUDDER,Rudder.this.getAngleCouvert(radian));}}// 如果手指离开屏幕,则摇杆返回初始位置if (event.getAction() == MotionEvent.ACTION_UP) {MyRockerPosition = new Point(MyCtrlPoint);}return true;}// 获取摇杆偏移角度 0-360°private int getAngleCouvert(float radian) {int tmp = (int) Math.round(radian / Math.PI * 180);if (tmp < 0) {return -tmp;} else {return 180 + (180 - tmp);}}public interface RudderListener {void onSteeringWheelChanged(int action, int angle);}
}
3.自己定义了MathsSave类,里面有两个方法,分别为获得两点之间距离和和获取水平夹角弧度
import android.graphics.Point;
public class MathSave {
//获取两点间直线距离public static int getLength(float x1,float y1,float x2,float y2) {return (int)Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2));}public static Point getBorderPoint(Point a, Point b,int cutRadius) {float radian = getRadian(a, b);return new Point(a.x + (int)(cutRadius * Math.cos(radian)), a.x + (int)(cutRadius * Math.sin(radian)));}//获取水平线夹角弧度
public static float getRadian (Point a, Point b) {
float lenA = b.x-a.x;float lenB = b.y-a.y;float lenC = (float)Math.sqrt(lenA*lenA+lenB*lenB);float ang = (float)Math.acos(lenA/lenC);ang = ang * (b.y < a.y ? -1 : 1); return ang;}
}
4,在.xml下的布局如下实现
android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><ImageViewandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:scaleType="fitXY"/><RelativeLayoutandroid:id="@+id/ctrls"android:layout_width="fill_parent"android:layout_height="fill_parent" ><com.example.ball.Rudderandroid:id="@+id/rudder"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true" /></RelativeLayout>
最后就可以进行测试了,可以自己试着定义这个摇杆的背景颜色等,以及整个Activity的背景。
Android手机摇杆相关推荐
- HTC下一款Android手机即将上市
宏达电(HTC)新款Android手机的硬件规格细节逐渐浮上台面,其中最受瞩目的两款,Bravo和Supersonic,可望在近期内正式宣布.与Nexus One以及Sony Ericsson的Xpe ...
- Android手机指令操作释疑
有人问我一个关于Android手机root与否的问题,她说明明iTools显示已取得root权限,但她就是没法在该手机上运行需要root权限的App如钛备份等等.我告诉她最好的确认方式便是以adb指令 ...
- 扫盲:关于Android手机内存ROM、RAM还有SD卡的解释
买Android手机,除了CPU外,接下来最重要的可能就是ROM.RAM.SD卡的大小了.那就赶紧来了解一下手机内存ROM.RAM还有SD卡的重要性吧,不然在买手机的时候可能会吃亏. 因为一些手机厂家 ...
- 如何判断Android手机当前是否联网?
文章分类:移动开发 如果拟开发一个网络应用的程序,首先考虑是否接入网络,在Android手机中判断是否联网可以通过 ConnectivityManager 类的isAvailable()方法判断, 首 ...
- android x86小白安装教程,小白的教程,在windows上安装完美的Android手机驱动
无论什么Android手机,若想和电脑进行连接,都必须在电脑上面安装Android手机的USB连接驱动,这个过程非常简单,以下是相关的流程. 第一步,安装adb驱动,地址http://u.115.co ...
- android canvas 保存图片,ionic3 html5 video 抓图保存到手机相册,解决Android手机不支持Canvas drawImage问题...
当然百度出上W条答案 上代码,相信下面代码和小伙伴大同吧 相信好多做webview app的小伙伴们都有同样的问题,在pc上能轻松实现video 抓图.但是在android手机大多是不支持canvas ...
- Android手机启动流程与TEE OS
2019独角兽企业重金招聘Python工程师标准>>> 转载:https://cloud.tencent.com/developer/article/1043659 一个移植了TEE ...
- 屏幕按压力度android,android手机 N 所支持的压感技术
android手机实现压感技术并不是更换压感屏那么简单,由此带来的还有对系统层面的策划与开发,需要android手机软硬件相辅相成互相支持才可以更好的呈现给大家,不过现在android手机 N 将要直 ...
- android手机数字取证,基于Android智能终端微信应用的数字取证分析模型的研究
第 42卷 第 10A期 2015年 10月 计 算 机 科 学 Computer Science Vo1.42 No.10A Oct 2015 基于 Android智能终端微信应用的数字取证分析模型 ...
最新文章
- bzoj3467: Crash和陶陶的游戏
- python版mapreduce题目实现寻找共同好友
- Java HttpClient 4.3.1 访问ASP.NET WebService
- 十一、Python异常处理
- Android开发之添加QQ群的方法(官方代码)
- oracle display set,Check if the DISPLAY variable is set
- java akka_AKKA文档(java版)——什么是AKKA?
- 无线文件服务器,文件共享新方法 无线网络文件共享设置
- Python无参装饰器
- 高德开放平台与360儿童手表达成合作,全球数据助力第三方企业
- matlab 随机函数的使用
- VS2019如何修改字体大小
- 小心投机分子绿坝软件的苦肉计
- 机器学习基础:模糊C均值聚类(Machine Learning Fundamentals: Fuzzy C-Means )Python实现
- picsart旧版本_picsart旧版本中文下载-picsart老版本软件8.5.6 历史版本-东坡下载
- 用积木搭出的埃菲尔铁塔
- 单片机c语言双边拉幕灯,51单片机C语言入门教程
- 规划风险应对-规划过程组
- nodejs 系统 临时文件夹
- JAVA模拟HTTP请求中GET/POST方式
热门文章
- 【Linux从0到1】第十三篇:网络编程套接字
- Nexus私服(二)
- SEREN射频电源维修Seren电源维修R301MKⅡ SEREN射频匹配器维修
- 【Latex】在标题下插入头图 teaser
- 想要风投被你的融资 PPT 打动吗?别忘了你其实就是在想方设法卖出自己公司的部分股权...
- 微信服务通知消息找回_80%的人都不知道的10个微信冷知识,全都超实用!
- win7引导安装ubuntu无需U盘启动
- 解决Client not ready yet..Timed out waiting for process to appear on 无法自动启动安卓应用问题
- SSD 之BBM坏块管理机制
- 2021-11-3PS自学第5天——选区和选框工具