真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Android自定義控件如何實(shí)現(xiàn)方向盤效果

小編這次要給大家分享的是Android自定義控件如何實(shí)現(xiàn)方向盤效果,文章內(nèi)容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

創(chuàng)新互聯(lián)是一家專注于網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)與策劃設(shè)計(jì),利州網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:利州等地區(qū)。利州做網(wǎng)站價(jià)格咨詢:18980820575

在很多開發(fā)中,為了界面更加的友好,在自定義View的基礎(chǔ)上,開發(fā)者會開發(fā)出各種各樣的自定義控件來滿足實(shí)際開發(fā)需要,其中有一種”方向盤”的控件在實(shí)際開發(fā)中非常常見,便于用戶進(jìn)行一些實(shí)際性的方向控制。

在復(fù)習(xí)參考了許多自定義控件的基礎(chǔ)上,我實(shí)現(xiàn)了一個(gè)最最基本的方向盤空間,并且可以根據(jù)方向做出相應(yīng)的反應(yīng)。話不多說,先看看效果。

做的有點(diǎn)丑,大家可以看看實(shí)際原理,后期再優(yōu)化具體“方向盤”.

Android自定義控件如何實(shí)現(xiàn)方向盤效果

空間下面的幾行字是我為了確定方向所寫的一些參數(shù),基本思想就是在方向盤的中心確定一個(gè)坐標(biāo)軸,根據(jù)中間這個(gè)小圓的和中心點(diǎn)的距離與方向確定所處的方向。在手離開屏幕以后,小圓回到原點(diǎn)。

一言不合就放代碼~~~~

具體是怎么實(shí)現(xiàn)的呢??

來我們一起看看代碼,看完一目了然。

package com.sshhsun.socketudp.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class MyWheel extends View implements Runnable,View.OnTouchListener {

  public MyWheel(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
  }

  //先定義一些繪圖要用的基本參數(shù)
  public static final int BOTTOM = 7;
  public static final int BOTTOM_LEFT = 8;
  public static final long DEFAULT_LOOP_INTERVAL = 100L;
  public static final int FRONT = 3;
  public static final int FRONT_RIGHT = 4;
  public static final int LEFT = 1;
  public static final int LEFT_FRONT = 2;
  public static final int RIGHT = 5;
  public static final int RIGHT_BOTTOM = 6;
  private final double RAD = 57.295779500000002D;
  private Paint button;
  private int buttonRadius;
  public double centerX = 0.0D;
  public double centerY = 0.0D;
  private Paint horizontalLine;
  private int joystickRadius;
  private int lastAngle = 0;
  private int lastPower = 0;
  private long loopInterval = 100L;
  private Paint mainCircle;  //整個(gè)控件的大圓,及小紅點(diǎn)的活動范圍


  //自定義的接口用于監(jiān)聽處理控件的觸摸事件
  private OnMyWheelMoveListener onmywheelMoveListener;
  private Paint secondaryCircle;//第二個(gè)內(nèi)圓,小紅圓超過后開始處理角度
  private Thread thread = new Thread(this);
  private Paint verticalLine;
  private int xPosition = 0;
  private int yPosition = 0;
  private static final String tag="MyWheel";

  public MyWheel(Context paramContext, AttributeSet paramAttributeSet) {
    super(paramContext, paramAttributeSet);
    initMyWheel();  //好吧,我知道MyWheel這個(gè)名字有點(diǎn)太隨便了........
  }

  public MyWheel(Context paramContext, AttributeSet paramAttributeSet,
      int paramInt) {
    super(paramContext, paramAttributeSet, paramInt);
    initMyWheel();
  }

  //根據(jù)所處的位置得到角度
  private int getAngle() {
    if (this.xPosition > this.centerX) {
      if (this.yPosition < this.centerY) {
        int m = (int) (90.0D + 57.295779500000002D * Math
            .atan((this.yPosition - this.centerY)
                / (this.xPosition - this.centerX)));
        this.lastAngle = m;
        return m;
      }
      if (this.yPosition > this.centerY) {
        int k = 90 + (int) (57.295779500000002D * Math
            .atan((this.yPosition - this.centerY)
                / (this.xPosition - this.centerX)));
        this.lastAngle = k;
        return k;
      }
      this.lastAngle = 90;
      return 90;
    }
    if (this.xPosition < this.centerX) {
      if (this.yPosition < this.centerY) {
        int j = (int) (57.295779500000002D * Math
            .atan((this.yPosition - this.centerY)
                / (this.xPosition - this.centerX)) - 90.0D);
        this.lastAngle = j;
        return j;
      }
      if (this.yPosition > this.centerY) {
        int i = -90
            + (int) (57.295779500000002D * Math
                .atan((this.yPosition - this.centerY)
                    / (this.xPosition - this.centerX)));
        this.lastAngle = i;
        return i;
      }
      this.lastAngle = -90;
      return -90;
    }
    if (this.yPosition <= this.centerY) {
      this.lastAngle = 0;
      return 0;
    }
    if (this.lastAngle < 0) {
      this.lastAngle = -180;
      return -180;
    }
    this.lastAngle = 180;
    return 180;
  }

  //根據(jù)紅色圓的距離和角度得到方向
  private int getDirection() {
    int k;
    int j = 0;
    int i;
    if ((this.lastPower == 0) && (this.lastAngle == 0)) {
      k = 0;
      return k;
    }

    if (this.lastAngle <= 0)
      j = 90 + -1 * this.lastAngle;
    while (true) {
      k = 1 + (j + 22) / 45;
      if (k <= 8) {
        break;
      }

      if (this.lastAngle <= 90) {
        j = 90 - this.lastAngle;
        continue;
      }
      j = 360 - (-90 + this.lastAngle);
    }
    return k;
  }

  //得到紅色圓與中心的距離
  private int getPower() {
    return (this.lastPower=(int) (100.0D * Math.sqrt((this.xPosition - this.centerX)
        * (this.xPosition - this.centerX)
        + (this.yPosition - this.centerY)
        * (this.yPosition - this.centerY)) / this.joystickRadius));
  }

  private int measure(int paramInt) {
    int i = View.MeasureSpec.getMode(paramInt);
    int j = View.MeasureSpec.getSize(paramInt);
    if (i == 0)
      return 200;
    return j;
  }


  //初始化一些基本參數(shù)
  protected void initMyWheel() {
    this.mainCircle = new Paint(1);
    this.mainCircle.setColor(Color.BLUE);
    this.mainCircle.setStrokeWidth(3.0f);
    this.mainCircle.setStyle(Paint.Style.STROKE);
    this.secondaryCircle = new Paint();
    this.secondaryCircle.setColor(-16711936);
    this.secondaryCircle.setStrokeWidth(3.0f);
    this.secondaryCircle.setStyle(Paint.Style.STROKE);
    this.verticalLine = new Paint();
    this.verticalLine.setStrokeWidth(5.0F);
    this.verticalLine.setColor(-65536);
    this.horizontalLine = new Paint();
    this.horizontalLine.setStrokeWidth(2.0F);
    this.horizontalLine.setColor(-16777216);
    this.button = new Paint(1);
    this.button.setColor(Color.RED);
    this.button.setStyle(Paint.Style.FILL);
  }

  //初始化以后繪制方向盤。
  protected void onDraw(Canvas paramCanvas) {
    this.centerX = (getWidth() / 2);
    this.centerY = (getHeight() / 2);
    paramCanvas.drawCircle((int) this.centerX, (int) this.centerY,
        this.joystickRadius, this.mainCircle);
    paramCanvas.drawCircle((int) this.centerX, (int) this.centerY,
        this.joystickRadius / 2, this.secondaryCircle);
    paramCanvas
        .drawLine((float) this.centerX, (float) this.centerY,
            (float) this.centerX,
            (float) (this.centerY - this.joystickRadius),
            this.verticalLine);
    paramCanvas.drawLine((float) (this.centerX - this.joystickRadius),
        (float) this.centerY,
        (float) (this.centerX + this.joystickRadius),
        (float) this.centerY, this.horizontalLine);
    paramCanvas
        .drawLine((float) this.centerX,
            (float) (this.centerY + this.joystickRadius),
            (float) this.centerX, (float) this.centerY,
            this.horizontalLine);
    paramCanvas.drawCircle(this.xPosition, this.yPosition,
        this.buttonRadius, this.button);
  }

  protected void onFinishInflate() {
  }

  protected void onMeasure(int paramInt1, int paramInt2) {
    int i = Math.min(measure(paramInt1), measure(paramInt2));
    setMeasuredDimension(i, i);
  }

  protected void onSizeChanged(int paramInt1, int paramInt2, int paramInt3,
      int paramInt4) {
    super.onSizeChanged(paramInt1, paramInt2, paramInt3, paramInt4);
    this.xPosition = (getWidth() / 2);
    this.yPosition = (getWidth() / 2);
    int i = Math.min(paramInt1, paramInt2);
    this.buttonRadius = (int) (0.20D * (i / 2));
    this.joystickRadius = (int) (0.75D * (i / 2));
  }

  @Override
  public boolean onTouchEvent(MotionEvent paramMotionEvent) {
    //根據(jù)手觸碰的坐標(biāo)決定紅色小圓的位置
    this.xPosition = (int) paramMotionEvent.getX();
    this.yPosition = (int) paramMotionEvent.getY();
    double d = Math.sqrt((this.xPosition - this.centerX)
        * (this.xPosition - this.centerX)
        + (this.yPosition - this.centerY)
        * (this.yPosition - this.centerY));
    if (d > this.joystickRadius) {
      this.xPosition = (int) ((this.xPosition - this.centerX)
          * this.joystickRadius / d + this.centerX);
      this.yPosition = (int) ((this.yPosition - this.centerY)
          * this.joystickRadius / d + this.centerY);
    }
    invalidate();//再重新繪制
    if (paramMotionEvent.getAction() == 1) {
      this.xPosition = (int) this.centerX;
      this.yPosition = (int) this.centerY;
      this.thread.interrupt();
      if (this.onmywheelMoveListener != null)
        this.onmywheelMoveListener.onValueChanged(getAngle(),
            getPower());
    }
    if ((this.onmywheelMoveListener != null)
        && (paramMotionEvent.getAction() == 0)) {
      if ((this.thread != null) && (this.thread.isAlive()))
        this.thread.interrupt();
      this.thread = new Thread(this);
      this.thread.start();
      if (this.onmywheelMoveListener != null)
        //自定義接口處理觸摸事件
        this.onmywheelMoveListener.onValueChanged(getAngle(),
            getPower());
    }
    return true;
  }

  @Override
  public void run() {
    while (true) {
      if (Thread.interrupted())
        return;
      post(new Runnable() {
        public void run() {
//         Log.e(tag, "運(yùn)行在"+Thread.currentThread().getName()+"線程中");
          if (MyWheel.this.onmywheelMoveListener != null)
            MyWheel.this.onmywheelMoveListener.onValueChanged(
                MyWheel.this.getAngle(),
                MyWheel.this.getPower());
        }
      });
      try {
        Thread.sleep(this.loopInterval);
      } catch (InterruptedException localInterruptedException) {
      }
    }
  }
  public void setOnMyWheelMoveListener(
      OnMyWheelMoveListener paramOnJoystickMoveListener, long paramLong) {
    this.onmywheelMoveListener = paramOnJoystickMoveListener;
    this.loopInterval = paramLong;
  }

  public static abstract interface OnMyWheelMoveListener {
    public abstract void onValueChanged(int paramInt1, int paramInt2);
  }

  @SuppressLint("ClickableViewAccessibility")
  @Override
  public boolean onTouch(View v, MotionEvent event) {
    /*處理這個(gè)控件的觸摸事件*/
    return true;
  }
}

怎么用?下面我給出我的調(diào)用實(shí)例進(jìn)行講解

首先在XML文件中應(yīng)用。



  

    

在一個(gè)Fragment中引用實(shí)例并處理相應(yīng)監(jiān)聽事件。

package com.sshhsun.socketudp.fragment;

import android.content.Context;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView.FindListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

import com.sshhsun.socketudp.R;
import com.sshhsun.socketudp.activity.constant.Constant;
import com.sshhsun.socketudp.utils.MyWheel;
import com.sshhsun.socketudp.utils.MyWheel.OnMyWheelMoveListener;
import com.sshhsun.socketudp.utils.UDPUtil;

public class SimpleFragment extends Fragment implements View.OnClickListener {

  private MyWheel mtwheel;
  private TextView notice;
  private TextView show;
  private String direction = "none";
  private SeekBar seekbar;
  private static final String tag = "SimpleFragment";
  Vibrator vibator;
  private Context context = getActivity();
  private boolean isturn = false;
  private Button stand;
  private Button sit;
  private Button standinit;
  private Button rest;
  private Button standzero;
  private UDPUtil udpUtil;
  private boolean issend = false;
  private boolean isstop = true;

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) {
    return initView(inflater, container, savedInstanceState);
  }

  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    initData();
    initListener();
  }

  public View initView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.frag_simple, null);

    //我的方向盤控件mtwheel
    mtwheel = (MyWheel) view.findViewById(R.id.mywheel);

    //控件下面的提示信息notice,其他控件大家可以忽略.
    notice = (TextView) view.findViewById(R.id.notice);
    seekbar = (SeekBar) view.findViewById(R.id.turns);
    seekbar.setProgress(50);
    stand = (Button) view.findViewById(R.id.simple_stand);
    sit = (Button) view.findViewById(R.id.simple_sit);
    standinit = (Button) view.findViewById(R.id.simple_standinit);
    rest = (Button) view.findViewById(R.id.simple_rest);
    standzero = (Button) view.findViewById(R.id.simple_standzero);
    return view;
  }

  public void initListener() {
    sit.setOnClickListener(this);
    standinit.setOnClickListener(this);
    rest.setOnClickListener(this);
    standzero.setOnClickListener(this);
    stand.setOnClickListener(this);


    //下面的監(jiān)聽器代碼最為重要!?。。。。。?!
    mtwheel.setOnMyWheelMoveListener(new OnMyWheelMoveListener() {

      @Override
      // paramInt1:角度
      // paramInt2:距離 根據(jù)這兩個(gè)參數(shù)可以算出方向盤的方位
      public void onValueChanged(int paramInt1, int paramInt2) {
        boolean isdistance = false;
        if (paramInt2 >= 50) {
          isdistance = true;
          int temp = Math.abs(paramInt1);
          if (paramInt1 >= 0) {
            if (temp > 50 && temp < 120) {
              direction = "right";
              if (!issend) {
                udpUtil.UdpSend(direction, Constant.port);
                issend = true;
                isstop = false;
              }
            } else if (temp < 40) {
              direction = "forward";
              if (!issend) {
                udpUtil.UdpSend(direction, Constant.port);
                issend = true;
                isstop = false;
              }
            } else if (temp > 140) {
              direction = "back";
              if (!issend) {
                udpUtil.UdpSend(direction, Constant.port);
                issend = true;
                isstop = false;
              }
            } else {
              direction = "指向不明確";
              issend = false;
            }
          } else {
            if (temp > 50 && temp < 120) {
              direction = "left";
              if (!issend) {
                udpUtil.UdpSend(direction, Constant.port);
                issend = true;
                isstop = false;
              }
            } else if (temp < 40) {
              direction = "forward";
              if (!issend) {
                udpUtil.UdpSend(direction, Constant.port);
                issend = true;
                isstop = false;
              }
            } else if (temp > 140) {
              direction = "back";
              if (!issend) {
                udpUtil.UdpSend(direction, Constant.port);
                issend = true;
                isstop = false;
              }
            } else {
              direction = "指向不明確";
              issend = false;
            }
          }
        } else {
          isdistance = false;
          direction = "stop";
          issend = false;
        }
        notice.setText(" getAngle:" + paramInt1 + "\n" + " getPower:"
            + paramInt2 + "\n" + "direction:" + direction);

        if (direction.equals("stop") && (!isstop)) {
          udpUtil.UdpSend(direction, Constant.port);
          isstop = true;
        }
      }
    }, 100L);
    seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

      @Override
      public void onStopTrackingTouch(SeekBar seekBar) {
        seekbar.setProgress(50);
        isturn = false;
        String command = "stop";
        udpUtil.UdpSend(command, Constant.port);
      }

      @Override
      public void onStartTrackingTouch(SeekBar seekBar) {

      }

      @Override
      public void onProgressChanged(SeekBar seekBar, int progress,
          boolean fromUser) {
        int cucrrent = seekbar.getProgress();
        String command = "hello";
        if (cucrrent < 20) {
          Toast.makeText(getActivity(), "onProgressChanged" + "左轉(zhuǎn)", 0)
              .show();
          if (!isturn) {
            Log.e(tag, "onProgressChanged" + "左轉(zhuǎn)");
            command = "turnleft";
            udpUtil.UdpSend(command, Constant.port);
            vibator.vibrate(100);
            isturn = true;
          }
        } else if (cucrrent > 80) {
          Toast.makeText(getActivity(), "onProgressChanged" + "右轉(zhuǎn)", 0)
              .show();
          if (!isturn) {
            Log.e(tag, "onProgressChanged" + "右轉(zhuǎn)");
            command = "turnright";
            udpUtil.UdpSend(command, Constant.port);
            vibator.vibrate(100);
            isturn = true;
          }
        }
      }
    });

  }

  public void initData() {
    udpUtil = new UDPUtil(Constant.Address);
    vibator = (Vibrator) getActivity().getSystemService(
        Context.VIBRATOR_SERVICE);
    Thread.currentThread().setName(tag);
  }

  public void processClick(View v) {
    String command = "hello";
    switch (v.getId()) {
    case R.id.simple_rest:
      command = "rest";
      break;
    case R.id.simple_sit:
      command = "sit";

      break;
    case R.id.simple_stand:
      command = "stand";

      break;
    case R.id.simple_standinit:
      command = "standinit";

      break;
    case R.id.simple_standzero:
      command = "standzero";

      break;
    default:
      break;
    }
    udpUtil.UdpSend(command, Constant.port);
  }

  @Override
  public void onClick(View v) {
    processClick(v);
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    vibator.cancel();
  }
  // @Override
  // public boolean onTouch(View v, MotionEvent event) {
  // if (v.getId() == R.id.turns) {
  // String notice = "";
  // switch (event.getAction()) {
  // case MotionEvent.ACTION_DOWN:
  // notice = "ACTION_DOWN"+event.getX();
  // int process=(int) Math.floor(event.getX()+0.5);
  // seekbar.setProgress(process);
  // break;
  // case MotionEvent.ACTION_UP:
  // notice = "ACTION_UP";
  // break;
  // case MotionEvent.ACTION_CANCEL:
  // notice = "ACTION_CANCEL";
  // break;
  // default:
  // break;
  // }
  // if (!TextUtils.isEmpty(notice)) {
  // Toast.makeText(getActivity(), notice, 0).show();
  // }
  // }
  // return true;
  // }

}

聲明一下:

1.上面的控件代碼(第一部分代碼)可以實(shí)際使用
2.第二部分代碼演示了控件的使用與處理
3.關(guān)于控件的實(shí)現(xiàn)原理和思想在代碼與注釋中已經(jīng)詳細(xì)標(biāo)記

看完這篇關(guān)于Android自定義控件如何實(shí)現(xiàn)方向盤效果的文章,如果覺得文章內(nèi)容寫得不錯(cuò)的話,可以把它分享出去給更多人看到。


本文題目:Android自定義控件如何實(shí)現(xiàn)方向盤效果
URL鏈接:http://weahome.cn/article/pdpogs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部