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

这篇博客介绍了如何在Android中自定义一个摇杆控件,包括使用两张图片作为背景和摇杆,创建XML布局文件,定义自定义属性,编写自定义View类以及处理触摸事件,最终实现在主活动中监听并响应摇杆的变化。

效果图

3169711ed13801eedac633f6b7069d34.png

1.找两张图片

1)Joystick背景图片circle_1.png

686d67d701ba8e2b1e84a02142465f32.png

2)Joystick图片circle_2.png

1f905ba945cc6e1601a412c7351bd7b4.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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值