效果图

1.找两张图片

1)Joystick背景图片circle_1.png

2)Joystick图片circle_2.png

2.在layout中创建布局文件 imagejoystick.xml

内容为:

xml version="1.0"encoding="utf-8"?>

xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent">android:layout_width="match_parent"android:layout_height="match_parent">android:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/ivBackground"android:layout_gravity="center"android:src="@drawable/circle_1"/>android:layout_width="100dp"android:layout_height="100dp"android:id="@+id/ivJoystick"android:src="@drawable/circle_2"android:visibility="visible"/>

效果如图:

3.在value文件夹中添加sttrs.xml文件,添加控件属性,内容为

//可以是自定义控件名也可以是其它的

format: reference 资源ID

color   颜色

boolean  布尔变量

dimension 尺寸值

float     浮点值

integer       整形值

string 字符串

fraction 百分比

enum枚举值

flag  位或运算

4.在工程目录下添加自定义控件文件JoystickView

//JoystickView

package com.innovpower.uav.CustomView;

import android.content.Context;

import android.content.res.TypedArray;

import android.util.AttributeSet;

import android.util.Log;

import android.view.LayoutInflater;

import android.view.MotionEvent;

import android.view.View;

import android.widget.FrameLayout;

import android.widget.ImageView;

import android.widget.LinearLayout;

import com.innovpower.uav.R;

/**

* Created by ${chenxi} on 2015/12/8.

*/

public class JoystickView extends LinearLayout {

private View inflate;

private int backgroundDiameter;

private int joystickDiameter;

private FrameLayout.LayoutParams layoutParams;

private ImageView ivJoystick;

private ImageView ivBackground;

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

public JoystickView(Context context) {

super(context);

inflate = LayoutInflater.from(context).inflate(R.layout.imagejoystick, this, true);

ivJoystick = (ImageView) inflate.findViewById(R.id.ivJoystick);

ivBackground = (ImageView) inflate.findViewById(R.id.ivBackground);

}

public JoystickView(Context context, AttributeSet attrs) {

super(context, attrs);

inflate = LayoutInflater.from(context).inflate(R.layout.imagejoystick, this, true);

ivJoystick = (ImageView) inflate.findViewById(R.id.ivJoystick);

ivBackground = (ImageView) inflate.findViewById(R.id.ivBackground);

TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.JoystickView); //与属性名称一致

backgroundDiameter = (int) array.getDimension(R.styleable.JoystickView_backgroundDiameter, 40);//第一个是传递参数,第二个是默认值

joystickDiameter = (int) array.getDimension(R.styleable.JoystickView_joystickDiameter, 40);

}

@Override

protected void onAttachedToWindow() {

super.onAttachedToWindow();

initBackground(0, 0);

layoutParams = (FrameLayout.LayoutParams) ivJoystick

.getLayoutParams();

layoutParams.height = joystickDiameter;

layoutParams.width = joystickDiameter;

ivJoystick.setLayoutParams(layoutParams);

ivJoystick.setVisibility(INVISIBLE);

}

@Override

protected void onDetachedFromWindow() {

super.onDetachedFromWindow();

}

@Override

public boolean onTouchEvent(MotionEvent event) {

int xOrigin = getWidth() / 2 - joystickDiameter / 2;

int yOrigin = getHeight() / 2 - joystickDiameter / 2;

int x_touch = (int) event.getX() - joystickDiameter / 2;

int y_touch = (int) event.getY() - joystickDiameter / 2;

int limit = backgroundDiameter / 2 - joystickDiameter / 2;

if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {

ivJoystick.setVisibility(VISIBLE);

//得到摇杆与触屏点所形成的角度

double tempRad = getRad(xOrigin, yOrigin, x_touch, y_touch);

if (Math.sqrt(Math.pow((xOrigin - x_touch), 2) + Math.pow((yOrigin - y_touch), 2)) >= limit) {

//保证内部小圆运动的长度限制

getXY(xOrigin, yOrigin, limit, tempRad);

} else {//如果小球中心点小于活动区域则随着用户触屏点移动即可

Stickmove(x_touch, y_touch);

}

if (listener!=null)

listener.onSteeringWheelChanged(radToAngle(tempRad));

} else if (event.getAction() == MotionEvent.ACTION_UP) {

//当释放按键时摇杆要恢复摇杆的位置为初始位置

Stickmove(xOrigin, yOrigin);

ivJoystick.setVisibility(INVISIBLE);

}

return true;

}

private double radToAngle(double rad){

return (180*rad)/Math.PI;

}

private void initBackground(int x, int y) {//将背景圆移动到中心

FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) ivBackground

.getLayoutParams();

layoutParams.leftMargin = x;

layoutParams.topMargin = y;

layoutParams.width = backgroundDiameter;

layoutParams.height = backgroundDiameter;

ivBackground.setLayoutParams(layoutParams);

}

private void Stickmove(int x, int y) {

layoutParams.leftMargin = x;

layoutParams.topMargin = y;

ivJoystick.setLayoutParams(layoutParams);

}

/***

* 得到两点之间的弧度

*/

private 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坐标

5.在布局中调用控件

xmlns:tools="http://schemas.android.com/tools"

xmlns:my_attrs="http://schemas.android.com/apk/res-auto"

(eclipse/IDEA :xmlns:custom="http://schemas.android.com/apk/res/com.XXX")

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

android:paddingBottom="@dimen/activity_vertical_margin"

tools:context=".MainActivity">

android:layout_height="wrap_content" />

android:layout_width="300dp"

android:layout_height="300dp"

my_attrs:backgroundDiameter="200dp"

my_attrs:joystickDiameter="100dp"

>

6.在mainacitivity中调用控件事件

publicclass MainActivity extends Activity {

private JoystickView joystick;

@Override

protected void onCreate(BundlesavedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

joystick=(JoystickView)findViewById(R.id.myJoystick);

joystick.setJoystickListener(newJoystickView.JoyStickListener() {

@Override

public voidonSteeringWheelChanged(int angle) {

Log.i("chenxi","angle:" + angle);

}

});

}

工程下载地址:

http://download.csdn.net/detail/cx415462822/9660342

Android自定义view摇杆,Android 自定义摇杆控件(使用图片)相关推荐

  1. Android技术分享| 【Android 自定义View】多人视频通话控件

    [Android 自定义View]多人视频通话控件 *以上图片截自微信等待中界面 等待中界面 上图是微信多人视频通话时未接通的界面状态,可见每个人的 View 中大致需包含了以下元素. 头像 昵称 L ...

  2. Android自定义View系列之进度指示控件

    我开通微信公众号啦,如果大家喜欢我的文章,欢迎大家关注我的微信号,我会定期为大家推送Android中的热门知识. 今天为大家介绍另一个自定义View--进度指示器,这个在电商App和支付宝等中经常遇到 ...

  3. Android Folding View(折叠视图、控件)

    很早之前看过有人求助以下这个效果是如何实现的, 也就是侧滑菜单的一个折叠效果,其实关于这个效果的实现,谷歌的一名工程师已经完成,并开放源码到devbytes上面了.如下面所示: 地址是:https:/ ...

  4. Qt自定义委托在QTableView中绘制控件、图片、文字

    自定义委托,继承于,QStyledItemDelegate类,重载Paint()函数, 1.实现在QTableView中绘制 格式字符串 2.实现在QTableView中绘制进度条 3.实现在QTab ...

  5. Android自定义View实现下拉刷新控件

    路过的老铁同志可以微信搜索"Android小菜",不定期更新Android技术文章.比CSDN更快一步阅读. 本文实现的功能如下: 1.支持下拉刷新: 2.支持上拉加载更多 3.刷 ...

  6. 自定义View 实现字母快速索引控件

    本篇实现的最终效果如下: 该自定义控件详细讲解请关注公众号:Android小菜. 公众号每日一更一篇安卓技术文章,更快更新,讲解更细致.

  7. Android自定义ViewGroup实现朋友圈九宫格控件

    在我们的实际应用中,经常需要用到自定义控件,比如自定义圆形头像,自定义计步器等等,这篇文章主要给大家介绍了关于Android自定义ViewGroup实现朋友圈九宫格控件的相关资料,需要的朋友可以参考下 ...

  8. Android 自定义View大全,Android中自定义View的实现方式总结大全

    Android自定义view是什么 在我们的日常开发中,很多时候系统提供的view是无法满足我们的需求的,例如,我们想给一个edittext加上清除按钮,等等. 这时候我们就需要对系统的view进行扩 ...

  9. android自定义view onmeasure,Android 重写ViewGroup 分析onMeasure()和onLayout()方法

    Android 重写ViewGroup 分析onMeasure()和onLayout()方法 在继承ViewGroup类时,需要重写两个方法,分别是onMeasure和onLayout. 1,在方法o ...

  10. android xml图片缩放,Android通过自定义ImageView控件实现图片的缩放和拖动的实现代码...

    概述:通过自定义ImageView控件,在xml布局里面调用自定的组件实现图片的缩放. /** * 自定义的ImageView控制,可对图片进行多点触控缩放和拖动 * * @author qiuwan ...

最新文章

  1. 「AI不惑境」数据压榨有多狠,人工智能就有多成功
  2. Tencent云联网灾备方案
  3. 西瓜说 | 物联网说了好一阵了,你为什么还不懂?
  4. log4j无法显示mybatis sql
  5. linux——grep、sed、awk整理及其比较
  6. boost::system模块实现新类别错误代码的创建和使用的测试程序
  7. php5..6中文帮助,6.5. IDE integration
  8. phpcmsV9发布文章后无法删除?后台找不到了?从phpmyadmin数据库删除吧!
  9. 模块的封装之C语言类的继承和派生
  10. 优酷宠爱剧场发布新片单 包括近30部待播精品剧
  11. 在类库文件无法使用Server.MapPath
  12. 计算机组成原理实验基本运算器,计算机组成原理运算器实验-20210611075033.docx-原创力文档...
  13. 如何不运用第三方变量实现两个数的交换
  14. 高通骁龙450智能模块msm8953 android 4G
  15. 最易懂得 鸿蒙 实战 - 真机调试 原子服务
  16. bvh动作 舞蹈_kinect动作捕捉初探(下)——bvh文件的处理和应用
  17. asp.net抓取163邮箱联系人实现代码
  18. uniapp中字体加粗问题
  19. 刚刚!阿里香港上市,他们的区块链和百度、腾讯有什么不同?
  20. 基于C语言实现的SML简单程序设计

热门文章

  1. 2013年9月25日星期三(demo5_2点法式平面)
  2. Gzip Zlib PNG 压缩算法【转】
  3. mysql导入sql文件、数据库时报错ERROR: ASCII '\0' appeared in the statement
  4. C语言:求ax²+bx+c=0方程的解
  5. [iOS]如何向 appstore 查询已发布 APP 的信息?
  6. Python for Maya DCC工具插件开发学习记录(一)
  7. python_day11(笔记及练习)
  8. icc色彩配置文件_什么是色彩配置文件?
  9. 安装和配置Anaconda需要注意的问题
  10. 比较器(Comparable与Comparator接口)