2011-12-05 2 views
9

Sto provando a trascinare e rilasciare un mirino su un MapView. Ho un pulsante ImageView sullo schermo. Quando lo tocco, il pulsante scompare e viene visualizzato un nuovo ImageView. Il nuovo ImageView dovrebbe sedersi centrato sotto il mio dito fino a quando non lo rilascerò da qualche parte, ma per qualche motivo l'offset non è corretto. Il mirino appare in basso a destra di dove sto toccando.Android 2.2 Fare clic e trascinare Centra immagine sotto tocco

L'immagine si sposta proporzionalmente quindi credo che il problema sia con lo offset_x e lo offset_y che definisco nella sezione ACTION_DOWN. Quindi, in ACTION_UP ho bisogno di createMarker(x,y) sulle coordinate corrette sotto il mio dito, ma anche quello è errato.

Ho provato vari modi per renderlo centrato, e alcuni sono migliori di altri. Finora non sono riuscito a farlo funzionare senza usare numeri magici.

Così com'è, sto utilizzando la posizione del clic e sottraendo metà della dimensione dell'immagine. Questo ha senso per me. È più vicino correggere se sottrai l'intera dimensione dell'immagine. Ho provato vari esempi dal web, tutti soffrono di inesattezze con la posizione View.

Potete darmi qualche consiglio?

crosshair = (ImageView)findViewById(R.id.crosshair); 
frameLayout = (FrameLayout)findViewById(R.id.mapframe); 
params = new LayoutParams(LayoutParams.WRAP_CONTENT, 
     LayoutParams.WRAP_CONTENT); 
crosshairImage = BitmapFactory.decodeResource(getResources(), R.drawable.crosshair); 
crosshair.setOnTouchListener(new OnTouchListener() { 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     if (event.getAction() == MotionEvent.ACTION_DOWN) { 
      dragStatus = START_DRAGGING; 

      // hide the button and grab a mobile crosshair 
      v.setVisibility(View.INVISIBLE); 
      image = new ImageView(getBaseContext()); 
      image.setImageBitmap(crosshairImage); 

      // set the image offsets to center the crosshair under my touch 
      offset_x = (int)event.getRawX() - (int)(crosshairImage.getWidth()/2) ; 
      offset_y = (int)event.getRawY() - (int)(crosshairImage.getHeight()/2) ; 

      // set the image location on the screen using padding 
      image.setPadding(offset_x, offset_y, 0, 0); 

      // add it to the screen so it shows up 
      frameLayout.addView(image, params); 
      frameLayout.invalidate(); 

      if(LOG_V) Log.v(TAG, "Pressed Crosshair"); 
      return true; 
     } else if (event.getAction() == MotionEvent.ACTION_UP) { 
      if(dragStatus == START_DRAGGING) { 
       dragStatus = STOP_DRAGGING; 

       // place a marker on this spot 
       makeMarker((int)event.getX() + offset_x, (int)event.getY() + offset_y); 

       // make the button visible again 
       v.setVisibility(View.VISIBLE); 

       // remove the mobile crosshair 
       frameLayout.removeView(image); 

       if(LOG_V) Log.v(TAG, "Dropped Crosshair"); 
       return true; 
      } 
     } else if (event.getAction() == MotionEvent.ACTION_MOVE) { 
      if (dragStatus == START_DRAGGING) { 
       // compute how far it has moved from 'start' offset 
       int x = (int)event.getX() + offset_x; 
       int y = (int)event.getY() + offset_y; 

       // check that it's in bounds 
       int w = getWindowManager().getDefaultDisplay().getWidth(); 
       int h = getWindowManager().getDefaultDisplay().getHeight(); 
       if(x > w) 
        x = w; 
       if(y > h) 
        y = h; 

       // set the padding to change the image loc 
       image.setPadding(x, y, 0 , 0); 

       // draw it 
       image.invalidate(); 
       frameLayout.requestLayout(); 

       if(LOG_V) Log.v(TAG, "(" + offset_x + ", " + offset_y + ")"); 

       return true; 
      } 
     }    
     return false; 
    } 

}); 
+0

sto ancora alla ricerca di una soluzione a questo, per qualche motivo non riesco a trovare un modo per mantenere il mirino centrato sotto il mio dito. So che AbsoluteLayout è deprecato ma inizierò a esplorare quella rotta. Pubblicherò se trovo qualcosa. – Lea

+0

È che l'immagine è ruotata in posizione di tocco – Vivekanand

+1

@Darunda Hai trovato la soluzione. Mi serve aiuto per favore? –

risposta

0

Hai scritto questo codice entro touch_Down.

offset_x = (int)event.getRawX() - (int)(crosshairImage.getWidth()/2) ; 
offset_y = (int)event.getRawY() - (int)(crosshairImage.getHeight()/2) ; 

// set the image location on the screen using padding 
image.setPadding(offset_x, offset_y, 0, 0); 

Provare a scriverlo al di fuori delle condizioni if, solo per assicurarsi che venga applicato a tutti gli eventi di tocco.

0

È possibile utilizzare nuove API disponibili in drag and drop

public boolean onTouch(View view, MotionEvent motionEvent) { 
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { 
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view); 
view.startDrag(null, shadowBuilder, view, 0); 
view.setVisibility(View.INVISIBLE); 
return true; 
} else { 
return false; 
} 
}