2016-12-16 38 views
0

我正在開發一個操縱桿按鈕。在圓周上移動時一切都可以,但是當我想將它向上或向下移動時,它只會從右側繞過圓圈。所以,我想要有兩種選擇(像真正的操縱桿一樣向上或向下移動)。這是我的代碼示例。感謝您的幫助ImageView onTouch不能上下移動,只能繞着圓圈運行

public class JoystickView extends FrameLayout implements View.OnTouchListener { 

    private Context context; 
    private ImageView backgroundImageView; 
    private ImageView buttonImageView; 
    private RelativeLayout relativeLayout; 
    private View rootView; 
    float xx = 0; 
    float yy = 0; 



    public JoystickView(Context context) { 
     super(context); 
     this.context = context; 
     setLayout(this); 
     buttonImageView.setOnTouchListener(this); 
     this.setClipChildren(false); 

    } 

    public void setLayout(ViewGroup view) { 

     FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 
     View v = inflateControlerLayout(); 
     view.addView(v, layoutParams); 
    } 

    protected View inflateControlerLayout() { 
     initSlider(); 
     rootView = relativeLayout; 
     return rootView; 

    } 


    public void initSlider() { 

     if (relativeLayout == null) { 
      relativeLayout = new RelativeLayout(context); 
      RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); 
      relativeLayout.setLayoutParams(layoutParams); 
      relativeLayout.setClipChildren(false); 
     } 

     if (backgroundImageView == null) { 
      backgroundImageView = new ImageView(context); 

      LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); 
      backgroundImageView.setLayoutParams(layoutParams); 

      // load image 
      try { 
       // get input stream 
       InputStream ims = getContext().getAssets().open("joystick_background.png"); 
       // load image as Drawable 
       Drawable d = Drawable.createFromStream(ims, null); 
       // set image to ImageView 
       backgroundImageView.setImageDrawable(d); 
      } catch (IOException ex) { 
       return; 
      } 
     } 

     if (buttonImageView == null) { 
      buttonImageView = new ImageView(context); 

      LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT, Gravity.CENTER); 

      buttonImageView.setLayoutParams(layoutParams); 


      // load image 
      try { 
       // get input stream 
       InputStream ims2 = getContext().getAssets().open("jostick_button.png"); 
       // load image as Drawable 
       Drawable d2 = Drawable.createFromStream(ims2, null); 
       // set image to ImageView 
       buttonImageView.setImageDrawable(d2); 
       buttonImageView.bringToFront(); 
      } catch (IOException ex) { 
       return; 
      } 
     } 

     if (relativeLayout != null) { 
      relativeLayout.addView(backgroundImageView); 
      relativeLayout.addView(buttonImageView); 
     } 
    } 

    @Override 
    public boolean onTouch(View view, MotionEvent motionEvent) { 


     switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) { 
      case MotionEvent.ACTION_DOWN: 

       break; 

      case MotionEvent.ACTION_UP: 
       view.setX(xx); 
       view.setY(yy); 
       break; 

      case MotionEvent.ACTION_POINTER_DOWN: 
       break; 

      case MotionEvent.ACTION_POINTER_UP: 
       break; 

      case MotionEvent.ACTION_MOVE: 


       float cx = view.getWidth()/2.f; 
       float cy = view.getHeight()/2.f; 
       float x = motionEvent.getRawX(); 
       float y = motionEvent.getRawY(); 
       float w = buttonImageView.getWidth(); 
       float h = buttonImageView.getHeight(); 

       double r = Math.min(cx, cy)/2.; 
       double dx = x - cx; 
       double dy = y - cy; 
       double hypot = Math.hypot(dx, dy); 
       double cos = dx/hypot; 
       double sin = dy/hypot; 
       double rdx = hypot < 1. ? 0. : r * cos; 
       double rdy = hypot < 1. ? 0. : r * sin; 

       buttonImageView.setTranslationX((float) (cx + rdx - w/2.)); 
       buttonImageView.setTranslationY((float) (cy + rdy - h/2.)); 

       break; 
     } 
     return true; 

    } 
} 

回答

1

這些線約束座標圓(橢圓形)路徑或中心:

  double rdx = hypot < 1. ? 0. : r * cos; 
      double rdy = hypot < 1. ? 0. : r * sin; 

對於hypot小於1(也就是1個像素),你必須是死的中心。

我改成了只約束圈內的座標:

  double rcos = r * cos; 
      double rsin = r * sin; 
      double rdx = Math.abs(dx) < Math.abs(rcos) ? dx : rcos; 
      double rdy = Math.abs(dy) < Math.abs(rsin) ? dy : rsin; 

我認爲這可能是你想要的。

+0

嗨克里斯,謝謝你快速回答,它的作品!現在,這讓我更加明白什麼是問題。但現在我正在處理另一件事。我想聽聽你的想法:它工作正常,我現在可以移動按鈕,上下左右等等。但現在當我用手指觸摸它的中心並嘗試移動它時,它從右下方開始(按鈕向右移動),手指中心尖端位於按鈕的左上角。我希望你明白我的意思......無論如何,謝謝你的解決方案! –

+0

我確實注意到了這種行爲。我認爲你必須從一個代碼片段開始,該代碼片段用於旋轉撥號盤或其他東西,因爲代碼適用於將視圖移動一圈。爲了得到你想要的行爲,你可以保存指針向下事件的初始x/y座標,然後在指針移動事件中派生相對運動。嘗試自己做出這些更改;如果您遇到困難,請爲社區發佈另一個問題。 –

+0

Thanx kris求助!我找到了一個解決方案。 –

0

我已經找到了有效的解決方案,如果有人正在尋找它

私有點計算(浮法X,浮法Y){

float cx = buttonImageView.getWidth()/2.f; 
    float cy = buttonImageView.getHeight()/2.f; 

    double r = cx/2.; // vrednost radius 
    double dx = x; 
    double dy = y; 
    double hypot = Math.hypot(dx, dy); // izracun hipotenuze 
    double cos = dx/hypot; // cos 
    double sin = dy/hypot; // sin 

    double rcos = r * cos; 
    double rsin = r * sin; 

    double rdx = Math.abs(dx) < Math.abs(rcos) ? dx : rcos; // if,else 
    double rdy = Math.abs(dy) < Math.abs(rsin) ? dy : rsin; 

    return new Point((int)rdx, (int)rdy); 

} 

@Override 
public boolean onTouch(View view, MotionEvent motionEvent) { 


    final float x = motionEvent.getRawX(); // x točko 
    final float y = motionEvent.getRawY(); // y točka 

    //Log.d("VALUES", "RAW X:" + motionEvent.getRawX() + ", RAW Y:" + motionEvent.getRawY() + ", X:" + motionEvent.getX() + ", CX:" + cx + ", CY:" + cy + ", dx:" + dx + ", dy:" + dy + ", Hypo:" + hypot + ", cos:" + cos + ", sin" + sin); 


    switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) { 
     case MotionEvent.ACTION_DOWN: 

      xDelta = view.getX() - x; 
      yDelta = view.getY() - y; 

      break; 

     case MotionEvent.ACTION_UP: 

      doBounceAnimation(buttonImageView); 
      doVibration(); 

      view.setX(xx); 
      view.setY(yy); 
      break; 

     case MotionEvent.ACTION_POINTER_DOWN: 
      break; 

     case MotionEvent.ACTION_POINTER_UP: 
      break; 

     case MotionEvent.ACTION_MOVE: 

      final float transX = (float) x; 
      final float transY = (float) y; 

      thread = new Thread() { 
       @Override 
       public void run() { 

        Point newPoint = calculate(transX+ xDelta,transY + yDelta); 
        buttonImageView.setX(newPoint.x); 
        buttonImageView.setY(newPoint.y); 
       } 
      }; 
      thread.start(); 




      Log.d(TRANSLATIONX,"X:" + transX + ", Y:" + transY); 

      break; 

    } 
    return true; 

} 

享受編碼!

相關問題