自定义摇杆控件

来源:互联网 发布:无锡有mac口红专柜吗 编辑:程序博客网 时间:2024/06/05 07:27

效果图


1.找两张图片

 1)Joystick背景图片circle_1.png


2)Joystick图片circle_2.png


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

内容为:

<?xml version="1.0"encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
             
android:orientation="vertical"
             
android:layout_width="match_parent"
             
android:layout_height="match_parent"
             
>

    <FrameLayout
           
android:layout_width="match_parent"
           
android:layout_height="match_parent"
           
>
        <ImageView
               
android:layout_width="wrap_content"
               
android:layout_height="wrap_content"
               
android:id="@+id/ivBackground"
                
android:layout_gravity="center"
               
android:src="@drawable/circle_1"/>
        <ImageView
               
android:layout_width="100dp"
               
android:layout_height="100dp"
               
android:id="@+id/ivJoystick"
                
android:src="@drawable/circle_2"
               
android:visibility="visible"
       
/>
    </FrameLayout>

 

效果如图:

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

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="JoystickView">//可以是自定义控件名也可以是其它的        <attr name="backgroundDiameter" format="dimension"/>        <attr name="joystickDiameter" format="dimension"/>    </declare-styleable></resources>

format: reference 资源ID

            color   颜色

            boolean  布尔变量

           dimension 尺寸值

           float     浮点值

           integer       整形值

           string 字符串

            fraction 百分比

       enum枚举值

            flag  位或运算

          

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

package com.demo.ui_weixin;import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.widget.FrameLayout;import android.widget.ImageView;import android.widget.LinearLayout;/** * 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);            if (Math.sqrt(Math.pow((xOrigin - x_touch), 2) + Math.pow((yOrigin - y_touch), 2)) >= limit) {                //得到摇杆与触屏点所形成的角度                double tempRad = getRad(xOrigin, yOrigin, x_touch, y_touch);                //保证内部小圆运动的长度限制                getXY(xOrigin, yOrigin, limit, tempRad);            } else {//如果小球中心点小于活动区域则随着用户触屏点移动即可                Stickmove(x_touch, y_touch);                listener.onSteeringWheelChanged(x_touch, y_touch);            }        } else if (event.getAction() == MotionEvent.ACTION_UP) {            //当释放按键时摇杆要恢复摇杆的位置为初始位置            Stickmove(xOrigin, yOrigin);            ivJoystick.setVisibility(INVISIBLE);        }        return true;    }    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);    }    /***     * 得到两点之间的弧度     */    public 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坐标<摇杆的Y坐标我们要取反值-0~-180        if (py2 < py1) {            rad = -rad;        }        return rad;    }    //函数:getXY    //功能:限制joystick移动范围不得大于R    //参数:centerX,centerY圆心的x,y    //     rad触点与圆心形成的直线与水平线之间的夹角    public void getXY(float centerX, float centerY, float R, double rad) {        int x, y;        //获取圆周运动的X坐标        x = (int) ((float) (R * Math.cos(rad)) + centerX);        //获取圆周运动的Y坐标        y = (int) ((float) (R * Math.sin(rad)) + centerY);        Stickmove(x, y);        listener.onSteeringWheelChanged(x,y);    }    // 设置回调接口    public void setJoystickListener(JoyStickListener rockerListener)    {        listener = rockerListener;    }    // 回调接口    public interface JoyStickListener    {        void onSteeringWheelChanged(int x, int y);    }}

5.在布局中调用控件

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"

    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">

 

    <TextViewandroid:text="@string/hello_world"android:layout_width="wrap_content"

       android:layout_height="wrap_content" />

 

   <com.demo.chenxi.joystickdemo.CustomView.JoystickView

        android:layout_width="300dp"

        android:layout_height="300dp"

       my_attrs:backgroundDiameter="200dp"

       my_attrs:joystickDiameter="100dp"

        >

 

       </com.demo.chenxi.joystickdemo.CustomView.JoystickView>

</RelativeLayout>

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 x, int y) {

                Log.i("chenxi","x:" + x + " " + "y:" + y);

            }

        });

    }

工程下载地址:

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

0 0