8

Tutti
Voglio ruotare l'immagine in un angolo particolare come nell'immagine qui sotto. Ho il codice per la rotazione, ma ruota di 360 gradi, ma lo voglio solo per gradi particolari e ottenere il numero selezionato che è il lato superiore del quadrante.
ruotare il quadrante in gradi limitati

enter image description here


sotto è il mio codice. La mia abitudine Guarda questo lavoro bene ma lago di perfomance.

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.PointF; 
import android.graphics.Rect; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.GestureDetector.OnGestureListener; 
import android.view.GestureDetector; 
import android.view.MotionEvent; 
import android.view.View; 

public class MyDialView extends View implements OnGestureListener{ 
    private static Bitmap bimmap; 
    private static Paint paint; 
    private static Rect bounds; 
    private int totalNicks = 100; 
    private int currentNick = 0; 
    private GestureDetector gestureDetector; 
    private float dragStartDeg = Float.NaN; 
    float dialerWidth = 0,dialerHeight = 0; 

    private static Paint createDefaultPaint() { 
     Paint paint = new Paint(); 
     paint.setAntiAlias(true); 
     paint.setFilterBitmap(true); 
     return paint; 
    } 
    private float xyToDegrees(float x, float y) { 
     float distanceFromCenter = PointF.length((x - 0.5f), (y - 0.5f)); 
     if (distanceFromCenter < 0.1f 
       || distanceFromCenter > 0.5f) { // ignore center and out of bounds events 
      return Float.NaN; 
     } else { 
      return (float) Math.toDegrees(Math.atan2(x - 0.5f, y - 0.5f)); 
     } 
    } 
    public final float getRotationInDegrees() { 
     return (360.0f/totalNicks) * currentNick; 
    } 

    public final void rotate(int nicks) { 
     currentNick = (currentNick + nicks); 
     if (currentNick >= totalNicks) { 
      currentNick %= totalNicks; 
     } else if (currentNick < 0) { 
      currentNick = (totalNicks + currentNick); 
     } 
     Log.e("Current nick", String.valueOf(currentNick)); 
     if((currentNick > 80 || currentNick < 20)){ 
      invalidate(); 
     } 
    } 
    public MyDialView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     bimmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.out_round); 
     paint = createDefaultPaint(); 
     gestureDetector = new GestureDetector(getContext(), this); 
     dialerWidth = bimmap.getWidth() /2.0f; 
     dialerHeight = bimmap.getHeight()/2.0f; 
     bounds = new Rect(); 
    } 



    @Override 
    protected void onDraw(Canvas canvas) { 
     canvas.getClipBounds(bounds); 
      canvas.save(Canvas.MATRIX_SAVE_FLAG); 
      //{ 
       canvas.translate(bounds.left, bounds.top); 

       float rotation = getRotationInDegrees(); 
       canvas.rotate(rotation, dialerWidth, dialerHeight); 
       canvas.drawBitmap(bimmap, 0,0,null); 
       //canvas.rotate(- rotation, dialerWidth, dialerHeight); 
      //}  
      canvas.restore(); 
    } 
    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if (gestureDetector.onTouchEvent(event)) { 
      return true; 
     } else { 
      return super.onTouchEvent(event); 
     } 
    } 
    //Gesture detector methods 
    @Override 
    public boolean onDown(MotionEvent e) { 
     float x = e.getX()/((float) getWidth()); 
     float y = e.getY()/((float) getHeight()); 

     dragStartDeg = xyToDegrees(x, y); 
     //Log.d("deg = " , ""+dragStartDeg); 
     if (! Float.isNaN(dragStartDeg)) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
      float velocityY) { 
     return false; 
    } 

    @Override 
    public void onLongPress(MotionEvent e) { 

    } 

    @Override 
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, 
      float distanceY) { 
     if (! Float.isNaN(dragStartDeg)) { 
      float currentDeg = xyToDegrees(e2.getX()/getWidth(), 
        e2.getY()/getHeight()); 

      if (! Float.isNaN(currentDeg)) { 
       float degPerNick = 360.0f/totalNicks; 
       float deltaDeg = dragStartDeg - currentDeg; 

       final int nicks = (int) (Math.signum(deltaDeg) 
         * Math.floor(Math.abs(deltaDeg)/degPerNick)); 

       if (nicks != 0) { 
        dragStartDeg = currentDeg; 
        rotate(nicks); 
       } 
      } 

      return true; 
     } else { 
      return false; 
     } 
    } 

    @Override 
    public void onShowPress(MotionEvent e) { 

    } 

    @Override 
    public boolean onSingleTapUp(MotionEvent e) { 
     return false; 
    } 

} 


Voglio 0-9 in base alla selezione dell'utente & consentire anche la rotazione all'utente di 0-9 non di più rotazione.

Ho anche controllato un altro codice questo è sotto.

dialer = (ImageView) findViewById(R.id.imageView_ring); 
     dialer.setOnTouchListener(new MyOnTouchListener()); 
     dialer.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 

      @Override 
      public void onGlobalLayout() { 
       // method called more than once, but the values only need to be initialized one time 
       if (dialerHeight == 0 || dialerWidth == 0) { 
        dialerHeight = dialer.getHeight(); 
        dialerWidth = dialer.getWidth(); 

        // resize 
        Matrix resize = new Matrix(); 
        resize.postScale((float)Math.min(dialerWidth, dialerHeight)/(float)imageOriginal.getWidth(), (float)Math.min(dialerWidth, dialerHeight)/(float)imageOriginal.getHeight()); 
        imageScaled = Bitmap.createBitmap(imageOriginal, 0, 0, imageOriginal.getWidth(), imageOriginal.getHeight(), resize, false); 

        // translate to the image view's center 
        float translateX = dialerWidth/2 - imageScaled.getWidth()/2; 
        float translateY = dialerHeight/2 - imageScaled.getHeight()/2; 
        matrix.postTranslate(translateX, translateY); 

        dialer.setImageBitmap(imageScaled); 
        dialer.setImageMatrix(matrix); 
        Log.e("Rotation degree :"+rotationDegrees, String.valueOf(tickNumber)); 
       } 
      } 
     }); 

int tickNumber = 0; 
    private void rotateDialer(float degrees) { 

     //System.out.println("Rotation Done :: "+rotationDone); 

     // if(!rotationDone) { 

      this.rotationDegrees += degrees; 
      this.rotationDegrees = this.rotationDegrees % 360; 

      tickNumber = (int)this.rotationDegrees*100/360; 
      // It could be negative 
      if (tickNumber > 0) tickNumber = 100 - tickNumber; 


      //this.rotationDegrees = Math.abs(rotationDegrees); 
      this.tickNumber = Math.abs(tickNumber); 

      if(tickNumber < 20 || tickNumber > 80){ 
       Log.e("Rotation degree :"+rotationDegrees, String.valueOf(tickNumber)); 
       matrix.postRotate(degrees, dialerWidth/2, dialerHeight/2); 
       dialer.setImageMatrix(matrix); 
      } 

     // } 
    } 
    /** 
    * @return The angle of the unit circle with the image view's center 
    */ 
    private double getAngle(double xTouch, double yTouch) { 

     double delta_x = xTouch - (dialerWidth) /2; 
     double delta_y = (dialerHeight) /2 - yTouch; 
     double radians = Math.atan2(delta_y, delta_x); 

     double dx = xTouch - dWidth; 
     double dy = (dHeight - ((dialerHeight) /2)) - yTouch; 
     double dRadi = Math.atan2(dy, dx); 
     //Log.e("MY degree", String.valueOf(Math.toDegrees(dRadi))); 
     //return Math.toDegrees(dRadi); 
     return Math.toDegrees(radians); 
    } 



    /** 
    * Simple implementation of an {@link OnTouchListener} for registering the dialer's touch events. 
    */ 
    private class MyOnTouchListener implements OnTouchListener { 

     private double startAngle; 

     @Override 
     public boolean onTouch(View v, MotionEvent event) { 

      switch (event.getAction()) { 

       case MotionEvent.ACTION_DOWN: 

        // reset the touched quadrants 
        /*for (int i = 0; i < quadrantTouched.length; i++) { 
         quadrantTouched[i] = false; 
        }*/ 

        //allowRotating = false; 

        startAngle = getAngle(event.getX(), event.getY()); 
        break; 

       case MotionEvent.ACTION_MOVE: 
        /*double rotationAngleRadians = Math.atan2(event.getX() - (dialer.getWidth()/2),  ((dialer.getHeight()/2) - event.getY())); 
        double angle = (int) Math.toDegrees(rotationAngleRadians); 
        Log.i("gg", "rotaion angle"+angle);*/ 

        double currentAngle = getAngle(event.getX(), event.getY()); 
        //if(currentAngle < 130 || currentAngle < 110){ 
         //Log.e("Start angle :"+startAngle, "Current angle:"+currentAngle); 
         rotateDialer((float) (startAngle - currentAngle)); 
         startAngle = currentAngle; 
        //} 


        //Log.e("MOVE start Degree:"+startAngle, "Current Degree :"+currentAngle); 
        break; 

       case MotionEvent.ACTION_UP: 
        //allowRotating = true; 
        break; 
      } 

      // set the touched quadrant to true 
      //quadrantTouched[getQuadrant(event.getX() - (dialerWidth/2), dialerHeight - event.getY() - (dialerHeight/2))] = true; 

      //detector.onTouchEvent(event); 

      return true; 
     } 
    } 
+0

Hai risolto il problema? Puoi condividere la tua soluzione? Grazie. –

risposta

2

Non capisco il tuo problema. Il codice sottostante ruota l'immagine di 48 gradi.

ImageView dialer = (ImageView) findViewById(R.id.imageView_ring); 

int degrees = 48; 
Matrix matrix = new Matrix(); 
matrix.setRotate(degrees); 
Bitmap bmpBowRotated = Bitmap.createBitmap(imageOrginal, 0, 0, imageOrginal.getWidth(),imageOrginal.getHeight(), matrix, false); 

dialer.setImageBitmap(bmpBowRotated); 
+0

ya che io sappia ma il mio codice funziona bene ma ruota l'immagine a 360 gradi ma voglio spostare l'immagine in base alla rotazione dell'utente in particolare solo il grado. Nella mia immagine ruota l'immagine solo da 1 a 10. –

2

Hi Girish c'è una classe denominata RotateAnimation utilizzando questa classe u può facilmente fare

 look Example like 

     RotateAnimation r = new RotateAnimation(0f, -90f,200,200); // HERE 
     r.setStartOffset(1000); 
     r.setDuration(1000); 
     r.setFillAfter(true); //HERE 
     animationSet.addAnimation(r); 
+0

spunta questa domanda Ho inserito il mio codice. –

0

Vorrei sapere prima che cosa ci sarà per la distribuzione? Permette la manipolazione di Evenets? in caso affermativo, mantieni l'evento ManipulationStatring e ManipulationDelta Event per ruotare l'elemento.
Se lo stesso non è il caso in cui Manipolazione non è disponibile, è possibile provare la proprietà RenderTransformation con RorateTransform dell'elemento in cui si sta lavorando con WPf.

+0

ya voglio la manipolazione posso aggiungere qualche codice di esempio? –

0

sono stato in grado di raggiungere questo obiettivo facendo alcune delle seguenti modifiche sul vostro codice

  1. Fare clic dell'utente esattamente sulla freccia sempre per ottenere l'angolo iniziale in cui è collocato la freccia, in il vostro caso 90 gradi, altrimenti restituisce false

  2. salvare anche l'angolo in cui l'utente ha rimosso il dito e l'uso che l'angolo come valore iniziale per il suo prossimo tatto, come se avesse messo la freccia a 100 gradi fare che la sua posizione iniziale tocco per attivare la rotazione di nuovo

  3. Ora, per il controllo la sua risposta prendere l'angolo in cui i numeri 0-9 sono posti, im indovinare i valori prendono 120 gradi da 0 a 9, dividere quell'angolo per 10, si può facilmente scoprire che cosa angolo rappresenta un valore che cosa e ottenere il risultato

anche toccando esattamente 90deg per iniziare la rotazione è molto irritante, in modo sempre verificare la presenza di valore che è di peso corporeo 90 + 4 e 90- 4 per iniziare, ma usa sempre il 90 come angolo iniziale Initial position at 0 Moved 60 degree

Problemi correlati