在一些手机游戏中,玩家可以通过虚拟控制盘来控制游戏角色的行动。 无人机和玩具操控App中也有这一类控制盘的应用。

用自定义View的方式来实现类似手柄的控件。

相关代码请见 github.com/RustFisher/…

JoystickView特性

目前JoystickView特性如下

  • 2种风格

    • 固定控制盘;
    • 浮动跟随模式;控制盘会移动到手指第一次点击的地方
  • 可以在背景上添加“箭头”,即添加效果图片
  • 自定义的“触摸球”图片和背景图片
  • 手指移出了控制盘范围,仍然能够保持追随
  • 能获取到移动位置的百分比参数

实现思路

用自定义View的方式实现这个控制盘。创建TouchView

控制盘的基本要求是跟随手指做出反应。为了获取到手指触屏的坐标,会用到View的onTouchEvent方法。

控件中的“触摸球”和背景由图片得来。在自定义view中先获取相应的bitmap,缩放成指定的尺寸。

onTouchEvent中获取到相应的坐标,计算出图片应该出现的位置;onDraw中根据坐标进行绘制。 计算出手指位置与控制盘中心的距离等信息,通过listener传递出去。

代码示例

样式设定

有固定和浮动这两种风格,未来可能还会添加

public enum PadStyle {FLOATING /* 随用户手指重新定位 */,FIXED    /* 固定位置 */
}
复制代码

控制盘配置

我们可以不直接操作TouchView,创建TouchViewModel存放相关的配置。

    private int bgResId;           // 背景图片资源IDprivate int touchBmpResId;     // 触摸图资源ID - 例如一个圆球private int directionPicResId; // 指示当前触摸点与圆心相对方向的图片IDprivate float mWholeViewWid;    // 整个View的宽private float mWholeViewHeight; // 整个View的高private float mWholePadWid;    // 盘的宽度,包括箭头;并不是View的总宽度private float mWholePadHeight; // 盘的高度,包括箭头;并不是View的总宽度private int mRoundBgRadius;    // 背景圆的半径 背景圆位置可以变化private int mTouchBallRadius = 100; // 触摸球的半径private int mRoundBgPadding;   // 背景圆到Pad边界的px  一般是留给方向箭头的位置private boolean showDirectionPic = false;    // 是否显示指示图片private PadStyle mPadStyle = PadStyle.FIXED; // 默认为固定位置的private PadLocationType mPadLocationType = PadLocationType.LEFT_BOT;// .........
复制代码

控制盘管理器

控制盘的配置项比较多,抽象出一个DefaultController来管理控制盘。这个控制器不是必要的。 管理器需要控制盘所在的父View,这里用的是RelativeLayout。

创建一个“左控制盘”。将各个尺寸配置传入。最后添加到containerView中。

    private void createLeftControlTouchView() {TouchViewModel model = new TouchViewModel(R.drawable.ui_pic_joystick_left_pad,R.drawable.ui_pic_joystick_control_ball);model.setWholeViewSize(ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_whole_field_wid),ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_whole_field_height));model.setPadSize(ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_pad_size),ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_pad_size));int roundBgRadius = ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_round_bg_radius);model.setContentSize(roundBgRadius, (int) (roundBgRadius / 3.5));model.setStyle(padStyle, PadLocationType.LEFT_BOT);model.setRoundBgPadding(ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_circle_bg_padding));leftControlTouchView = new TouchView(ctx);leftControlTouchView.init(model);// View的总大小RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_whole_field_wid),ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_whole_field_height));params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);leftControlTouchView.setLayoutParams(params);}// ............createLeftControlTouchView();containerView.addView(leftControlTouchView);
复制代码

管理器初始化时需要一个ViewGroup来承载控制盘。

    public DefaultController(Context context, RelativeLayout containerView, PadStyle padStyle) {this.ctx = context;this.containerView = containerView;this.padStyle = padStyle;}
复制代码

Fragment中使用

初始化管理器

初始化管理器,创建控制盘

    mDefaultController =new DefaultController(getContext(),(RelativeLayout) root.findViewById(R.id.joystick_container));mDefaultController.createViews();mDefaultController.showViews(false);
复制代码

设置监听器,获取用户的操作信息

通过控制器来设置监听器

        mDefaultController.setLeftTouchViewListener(new JoystickTouchViewListener() {@Overridepublic void onTouch(float horizontalPercent, float verticalPercent) {Log.d(TAG, "onTouch left: " + horizontalPercent + ", " + verticalPercent);}@Overridepublic void onReset() {Log.d(TAG, "onReset: left");}@Overridepublic void onActionDown() {Log.d(TAG, "onActionDown: left");}@Overridepublic void onActionUp() {Log.d(TAG, "onActionUp: left");}});
复制代码

至此,我们实现了一个简单的控制盘控件。在一些控制类应用中可以使用这个控件。

若想要做出更优美,更吸引人的控件,需要我们有好的审美水平。

Android - JoystickView 虚拟手柄,控制盘,自定义UI相关推荐

  1. Android中自定义农历日历,CalendarView Android 上一个优雅、万能自定义 UI、性能高效的日历控件,热插拔!热插拔!热插拔!重要的事 @codeKK Android开源站...

    An elegant CalendarView on Android platform. Freely draw UI with canvas, fast.efficient and low memo ...

  2. android 虚拟手柄

    最近因为想写个Android小游戏,其中涉及到虚拟手柄,于是写了这个demo 效果图: 通过自定义两个view来实现,并且通过回调 将手柄的的偏移量也就是滑动的距离,传递给目标运动的view ,运动的 ...

  3. android高德地图上加自定义菜单,自定义UI控件-UI界面定制-开发指南-Android 导航SDK | 高德地图API...

    关于自定义 UI 布局,您还可以参考官方Demo--完全自定义UI导航. 单元素自定义 可以通过AMapNaviViewOptions中如下接口进行单UI元素显示隐藏,只列出部分接口,更多功能请参考A ...

  4. android自定义UI模板图文详解

    不知道大家在实际开发中有没有自定义过UI模板?今天花时间研究了一下android中自定义UI模板,与大家分享一下. 每个设计良好的App都是自定义标题栏,在自定义标题栏的过程中大部分人可能都是自定义一 ...

  5. android虚拟手柄摇杆的实现

    最近的项目开发中的一个任务是实现Android虚拟手柄界面,如图所示: 界面是一个SurfaceView,摇杆和按键都是通过画图显示出来的,这里详细介摇杆的实现,当用户点击摇杆即中间的黄球时,然后可以 ...

  6. android 手柄摇杆代码,android虚拟手柄摇杆的实现

    最近的项目开发中的一个任务是实现Android虚拟手柄界面,如图所示: 界面是一个SurfaceView,摇杆和按键都是通过画图显示出来的,这里详细介摇杆的实现,当用户点击摇杆即中间的黄球时,然后可以 ...

  7. Android开发自定义UI组件

    Android开发自定义UI组件实现红色小球跟随手指移动 要写实现自定义UI组件,要创建一个BallView类,继承View类,在BallView类中创建画笔,然后重写OnDraw()方法和OnTou ...

  8. Android开源的精美日历控件,热插拔设计的万能自定义UI

    UI框架应该逻辑与界面实现分离,该日历控件使用了热插拔的设计 ,简单几步即可实现你需要的UI效果,热插拔的思想是你提供你的实现,我提供我的插座接口,与自定义Behavior是一样的思想. 听说第一页无 ...

  9. 基于socket实现虚拟手柄使用手机控制电脑游戏(下)-手机端虚拟手柄

    基于socket实现虚拟手柄使用手机控制电脑游戏(下)-手机端虚拟手柄 这个是关于利用socket套接字实现手机控制电脑按键的一个实例,完成这个项目可以实现用手机控制狂野飙车等游戏,就是一个简易的手机 ...

最新文章

  1. JavaScript+TensorFlow.js让你在视频中瞬间消失
  2. 【Qt】一个使用QEventLoop时,遇到的教训
  3. 小记,springboot项目中自己常用的logback配置文件
  4. 黑马lavarel教程---5、模型操作(AR模式)
  5. 渐进式迭代教学法--PHP
  6. 【学术相关】作者解读ICML接收论文:如何使用不止一个数据集训练神经网络模型?...
  7. 浅谈同步复位与异步复位
  8. mac好用大java_2020 最后,搞个 Mac 玩玩
  9. 万丰科技机器人排名_机器人系统集成“7宗最”
  10. C++PrimerPlus学习——第十三章编程练习
  11. 宝塔面板搭建autoPicCdn:一款基于jsdelivr-Github的免费CDN图床
  12. oracle一些基本命令
  13. 【Unity Shader】---UnityShader 提供的CG/HLSL语义
  14. 【OpenCV入门指南】第三篇Canny边缘检测
  15. linux刷新解析,如何在Linux(和FreeBSD)上刷新DNS解析器缓存
  16. proteus三输入与门_proteus元件对照
  17. TwinCAT软件部分参数介绍
  18. Vagrant在,win7/win10系统下搭建使用
  19. 企业征信报告的查询内容有哪些?
  20. 「CF1463A」暗黑地牢

热门文章

  1. mysql 增删改查
  2. 无法打开“Soundflower.pkg”,因为它来自身份不明的开发者。
  3. 根据中序和后序构造二叉树
  4. Unsupported format, or corrupt file: Expected BOF record; found b'[Localiz'
  5. 【转】论文阅读(Chenyi Chen——【ACCV2016】R-CNN for Small Object Detection)
  6. 全球与中国远程监考解决方案市场深度研究分析报告
  7. 考幼儿园高级园长证需要些什么材料
  8. MySQL语句——DDL、DML、DQL
  9. 阿里云ecs建站 一键环境配置 图文超详细_liunx下建站,适合纯新手小白
  10. blender php,=== 斑斓中国 Blender 知识索引 ===【初步整理】 nirenyang