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手机摇杆相关推荐

  1. HTC下一款Android手机即将上市

    宏达电(HTC)新款Android手机的硬件规格细节逐渐浮上台面,其中最受瞩目的两款,Bravo和Supersonic,可望在近期内正式宣布.与Nexus One以及Sony Ericsson的Xpe ...

  2. Android手机指令操作释疑

    有人问我一个关于Android手机root与否的问题,她说明明iTools显示已取得root权限,但她就是没法在该手机上运行需要root权限的App如钛备份等等.我告诉她最好的确认方式便是以adb指令 ...

  3. 扫盲:关于Android手机内存ROM、RAM还有SD卡的解释

    买Android手机,除了CPU外,接下来最重要的可能就是ROM.RAM.SD卡的大小了.那就赶紧来了解一下手机内存ROM.RAM还有SD卡的重要性吧,不然在买手机的时候可能会吃亏. 因为一些手机厂家 ...

  4. 如何判断Android手机当前是否联网?

    文章分类:移动开发 如果拟开发一个网络应用的程序,首先考虑是否接入网络,在Android手机中判断是否联网可以通过 ConnectivityManager 类的isAvailable()方法判断, 首 ...

  5. android x86小白安装教程,小白的教程,在windows上安装完美的Android手机驱动

    无论什么Android手机,若想和电脑进行连接,都必须在电脑上面安装Android手机的USB连接驱动,这个过程非常简单,以下是相关的流程. 第一步,安装adb驱动,地址http://u.115.co ...

  6. android canvas 保存图片,ionic3 html5 video 抓图保存到手机相册,解决Android手机不支持Canvas drawImage问题...

    当然百度出上W条答案 上代码,相信下面代码和小伙伴大同吧 相信好多做webview app的小伙伴们都有同样的问题,在pc上能轻松实现video 抓图.但是在android手机大多是不支持canvas ...

  7. Android手机启动流程与TEE OS

    2019独角兽企业重金招聘Python工程师标准>>> 转载:https://cloud.tencent.com/developer/article/1043659 一个移植了TEE ...

  8. 屏幕按压力度android,android手机 N 所支持的压感技术

    android手机实现压感技术并不是更换压感屏那么简单,由此带来的还有对系统层面的策划与开发,需要android手机软硬件相辅相成互相支持才可以更好的呈现给大家,不过现在android手机 N 将要直 ...

  9. android手机数字取证,基于Android智能终端微信应用的数字取证分析模型的研究

    第 42卷 第 10A期 2015年 10月 计 算 机 科 学 Computer Science Vo1.42 No.10A Oct 2015 基于 Android智能终端微信应用的数字取证分析模型 ...

最新文章

  1. bzoj3467: Crash和陶陶的游戏
  2. python版mapreduce题目实现寻找共同好友
  3. Java HttpClient 4.3.1 访问ASP.NET WebService
  4. 十一、Python异常处理
  5. Android开发之添加QQ群的方法(官方代码)
  6. oracle display set,Check if the DISPLAY variable is set
  7. java akka_AKKA文档(java版)——什么是AKKA?
  8. 无线文件服务器,文件共享新方法 无线网络文件共享设置
  9. Python无参装饰器
  10. 高德开放平台与360儿童手表达成合作,全球数据助力第三方企业
  11. matlab 随机函数的使用
  12. VS2019如何修改字体大小
  13. 小心投机分子绿坝软件的苦肉计
  14. 机器学习基础:模糊C均值聚类(Machine Learning Fundamentals: Fuzzy C-Means )Python实现
  15. picsart旧版本_picsart旧版本中文下载-picsart老版本软件8.5.6 历史版本-东坡下载
  16. 用积木搭出的埃菲尔铁塔
  17. 单片机c语言双边拉幕灯,51单片机C语言入门教程
  18. 规划风险应对-规划过程组
  19. nodejs 系统 临时文件夹
  20. JAVA模拟HTTP请求中GET/POST方式

热门文章

  1. 【Linux从0到1】第十三篇:网络编程套接字
  2. Nexus私服(二)
  3. SEREN射频电源维修Seren电源维修R301MKⅡ SEREN射频匹配器维修
  4. 【Latex】在标题下插入头图 teaser
  5. 想要风投被你的融资 PPT 打动吗?别忘了你其实就是在想方设法卖出自己公司的部分股权...
  6. 微信服务通知消息找回_80%的人都不知道的10个微信冷知识,全都超实用!
  7. win7引导安装ubuntu无需U盘启动
  8. 解决Client not ready yet..Timed out waiting for process to appear on 无法自动启动安卓应用问题
  9. SSD 之BBM坏块管理机制
  10. 2021-11-3PS自学第5天——选区和选框工具