Android - JoystickView 虚拟手柄,控制盘,自定义UI
在一些手机游戏中,玩家可以通过虚拟控制盘来控制游戏角色的行动。 无人机和玩具操控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相关推荐
- Android中自定义农历日历,CalendarView Android 上一个优雅、万能自定义 UI、性能高效的日历控件,热插拔!热插拔!热插拔!重要的事 @codeKK Android开源站...
An elegant CalendarView on Android platform. Freely draw UI with canvas, fast.efficient and low memo ...
- android 虚拟手柄
最近因为想写个Android小游戏,其中涉及到虚拟手柄,于是写了这个demo 效果图: 通过自定义两个view来实现,并且通过回调 将手柄的的偏移量也就是滑动的距离,传递给目标运动的view ,运动的 ...
- android高德地图上加自定义菜单,自定义UI控件-UI界面定制-开发指南-Android 导航SDK | 高德地图API...
关于自定义 UI 布局,您还可以参考官方Demo--完全自定义UI导航. 单元素自定义 可以通过AMapNaviViewOptions中如下接口进行单UI元素显示隐藏,只列出部分接口,更多功能请参考A ...
- android自定义UI模板图文详解
不知道大家在实际开发中有没有自定义过UI模板?今天花时间研究了一下android中自定义UI模板,与大家分享一下. 每个设计良好的App都是自定义标题栏,在自定义标题栏的过程中大部分人可能都是自定义一 ...
- android虚拟手柄摇杆的实现
最近的项目开发中的一个任务是实现Android虚拟手柄界面,如图所示: 界面是一个SurfaceView,摇杆和按键都是通过画图显示出来的,这里详细介摇杆的实现,当用户点击摇杆即中间的黄球时,然后可以 ...
- android 手柄摇杆代码,android虚拟手柄摇杆的实现
最近的项目开发中的一个任务是实现Android虚拟手柄界面,如图所示: 界面是一个SurfaceView,摇杆和按键都是通过画图显示出来的,这里详细介摇杆的实现,当用户点击摇杆即中间的黄球时,然后可以 ...
- Android开发自定义UI组件
Android开发自定义UI组件实现红色小球跟随手指移动 要写实现自定义UI组件,要创建一个BallView类,继承View类,在BallView类中创建画笔,然后重写OnDraw()方法和OnTou ...
- Android开源的精美日历控件,热插拔设计的万能自定义UI
UI框架应该逻辑与界面实现分离,该日历控件使用了热插拔的设计 ,简单几步即可实现你需要的UI效果,热插拔的思想是你提供你的实现,我提供我的插座接口,与自定义Behavior是一样的思想. 听说第一页无 ...
- 基于socket实现虚拟手柄使用手机控制电脑游戏(下)-手机端虚拟手柄
基于socket实现虚拟手柄使用手机控制电脑游戏(下)-手机端虚拟手柄 这个是关于利用socket套接字实现手机控制电脑按键的一个实例,完成这个项目可以实现用手机控制狂野飙车等游戏,就是一个简易的手机 ...
最新文章
- JavaScript+TensorFlow.js让你在视频中瞬间消失
- 【Qt】一个使用QEventLoop时,遇到的教训
- 小记,springboot项目中自己常用的logback配置文件
- 黑马lavarel教程---5、模型操作(AR模式)
- 渐进式迭代教学法--PHP
- 【学术相关】作者解读ICML接收论文:如何使用不止一个数据集训练神经网络模型?...
- 浅谈同步复位与异步复位
- mac好用大java_2020 最后,搞个 Mac 玩玩
- 万丰科技机器人排名_机器人系统集成“7宗最”
- C++PrimerPlus学习——第十三章编程练习
- 宝塔面板搭建autoPicCdn:一款基于jsdelivr-Github的免费CDN图床
- oracle一些基本命令
- 【Unity Shader】---UnityShader 提供的CG/HLSL语义
- 【OpenCV入门指南】第三篇Canny边缘检测
- linux刷新解析,如何在Linux(和FreeBSD)上刷新DNS解析器缓存
- proteus三输入与门_proteus元件对照
- TwinCAT软件部分参数介绍
- Vagrant在,win7/win10系统下搭建使用
- 企业征信报告的查询内容有哪些?
- 「CF1463A」暗黑地牢
热门文章
- mysql 增删改查
- 无法打开“Soundflower.pkg”,因为它来自身份不明的开发者。
- 根据中序和后序构造二叉树
- Unsupported format, or corrupt file: Expected BOF record; found b'[Localiz'
- 【转】论文阅读(Chenyi Chen——【ACCV2016】R-CNN for Small Object Detection)
- 全球与中国远程监考解决方案市场深度研究分析报告
- 考幼儿园高级园长证需要些什么材料
- MySQL语句——DDL、DML、DQL
- 阿里云ecs建站 一键环境配置 图文超详细_liunx下建站,适合纯新手小白
- blender php,=== 斑斓中国 Blender 知识索引 ===【初步整理】 nirenyang