Puoi farlo senza troppe complicazioni combinando:
- A
View.OnTouchListener
(per rilevare la sequenza di trascinamento, in pratica ACTION_DOWN
, ACTION_MOVE
, ..., ACTION_UP
). eccellente NineOldAndroids library biblioteca
- Jake Wharton, per supportare le animazioni vista proprietà prima livello di API 11.
In primo luogo, ottenere l'oggetto ImageView
e collegare il View.OnTouchListener
ad esso.
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
...
mImage = findViewById(...);
mImage.setOnTouchListener(mTouchListener);
}
In secondo luogo, il programma OnTouchListener
per catturare l'evento ACTION_DOWN
e memorizzare la coordinata iniziale tocco posizione X. Quindi, per ogni ACTION_MOVE
calcolare il delta (per la conversione e il ridimensionamento) e per ACTION_UP
restituire ImageView allo stato iniziale.
private View.OnTouchListener mTouchListener = new View.OnTouchListener()
{
private float mStartX;
@Override
public boolean onTouch(View v, MotionEvent event)
{
switch (event.getActionMasked())
{
case MotionEvent.ACTION_DOWN :
mStartX = event.getRawX();
return true;
case MotionEvent.ACTION_MOVE :
float currentX = event.getRawX();
animateTo(currentX - mStartX, true); // Snap to drag
return true;
case MotionEvent.ACTION_UP :
case MotionEvent.ACTION_CANCEL :
animateTo(0, false); // Ease back
return true;
}
return false;
}
};
Il animateTo()
sarebbe calcolato come segue. Il flag immediate
indica se la conversione e il ridimensionamento devono essere, beh, immediati (è vero quando si risponde a ciascun evento di spostamento e falso quando si ritorna alla sua posizione iniziale e scala).
private void animateTo(float displacement, boolean immediate)
{
final int EASE_BACK_DURATION = 300; // ms
int duration = (immediate ? 0 : EASE_BACK_DURATION);
Display display = getWindowManager().getDefaultDisplay();
int totalWidth = display.getWidth();
float scale = 1.0f - Math.abs(displacement/totalWidth);
ViewPropertyAnimator.animate(mImage)
.translationX(displacement)
.scaleX(scale)
.scaleY(scale)
.setDuration(duration)
.start();
}
Si consiglia di armeggiare con il ridimensionamento. Come scritto, significa che l'immagine sarà al 50% della sua dimensione originale quando viene trascinata fino al bordo dello schermo.
Questa soluzione dovrebbe funzionare senza problemi in livello API 8 (sebbene non l'abbia provata). L'essenza completa è available here se lo desideri.
funziona come il fascino :) grazie – Orr