2012-07-13 19 views
7

Ciao Sto usando il widget Galleria per mostrare le immagini scaricate da internet.Galleria Android zoom avanti/indietro

per mostrare più immagini e mi piacerebbe avere uno zoom graduale mentre le persone scivolano su e giù sullo schermo. So come implementare l'evento touch l'unica cosa che non so come far crescere gradualmente l'intera galleria. Non voglio ingrandire un'immagine. Voglio che l'intera galleria si ingrandisca/si allontani gradualmente.

EDIT3: riesco a ingrandire la parte visibile della galleria ma il problema è che ho bisogno di trovare un modo per la galleria per scoprirlo e aggiornare anche gli altri bambini.

Quello che succede è che se 3 immagini sono visibili poi si inizia lo zoom e la galleria non diventano più piccoli, in modo da fare le immagini, ma quello che vorrei in questo caso è più immagini per essere visibile, ma io non so come per raggiungere questo effetto desiderato. Ecco l'intero codice:

public class Gallery1 extends Activity implements OnTouchListener { 

private static final String TAG = "GalleryTest"; 
private float zoom=0.0f; 
// Remember some things for zooming 
PointF start = new PointF(); 
PointF mid = new PointF(); 
Gallery g; 
LinearLayout layout2; 
private ImageAdapter ad; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.gallery_1); 
    layout2=(LinearLayout) findViewById(R.id.layout2); 

    // Reference the Gallery view 
    g = (Gallery) findViewById(R.id.gallery); 
    // Set the adapter to our custom adapter (below) 
    ad=new ImageAdapter(this); 
    g.setAdapter(ad); 


    layout2.setOnTouchListener(this); 

} 


public void zoomList(boolean increase) { 
    Log.i(TAG, "startig animation"); 


    AnimatorSet set = new AnimatorSet(); 
    set.playTogether(

     ObjectAnimator.ofFloat(g, "scaleX", zoom), 
     ObjectAnimator.ofFloat(g, "scaleY", zoom) 

    ); 
    set.addListener(new AnimatorListener() { 

     @Override 
     public void onAnimationStart(Animator animation) { 


     } 

     @Override 
     public void onAnimationRepeat(Animator animation) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onAnimationEnd(Animator animation) { 

     } 

     @Override 
     public void onAnimationCancel(Animator animation) { 
      // TODO Auto-generated method stub 

     } 
    }); 
    set.setDuration(100).start(); 


} 


public class ImageAdapter extends BaseAdapter { 
    private static final int ITEM_WIDTH = 136; 
    private static final int ITEM_HEIGHT = 88; 

    private final int mGalleryItemBackground; 
    private final Context mContext; 

    private final Integer[] mImageIds = { 
      R.drawable.gallery_photo_1, 
      R.drawable.gallery_photo_2, 
      R.drawable.gallery_photo_3, 
      R.drawable.gallery_photo_4, 
      R.drawable.gallery_photo_5, 
      R.drawable.gallery_photo_6, 
      R.drawable.gallery_photo_7, 
      R.drawable.gallery_photo_8 
    }; 

    private final float mDensity; 

    public ImageAdapter(Context c) { 
     mContext = c; 
     // See res/values/attrs.xml for the <declare-styleable> that defines 
     // Gallery1. 
     TypedArray a = obtainStyledAttributes(R.styleable.Gallery1); 
     mGalleryItemBackground = a.getResourceId(
       R.styleable.Gallery1_android_galleryItemBackground, 1); 
     a.recycle(); 

     mDensity = c.getResources().getDisplayMetrics().density; 
    } 

    public int getCount() { 
     return mImageIds.length; 
    } 

    public Object getItem(int position) { 
     return position; 
    } 

    public long getItemId(int position) { 
     return position; 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     ImageView imageView; 
     if (convertView == null) { 
      convertView = new ImageView(mContext); 

      imageView = (ImageView) convertView; 
      imageView.setScaleType(ImageView.ScaleType.FIT_XY); 
      imageView.setLayoutParams(new Gallery.LayoutParams(
        (int) (ITEM_WIDTH * mDensity + 0.5f), 
        (int) (ITEM_HEIGHT * mDensity + 0.5f))); 

     } else { 
      imageView = (ImageView) convertView; 
     } 

     imageView.setImageResource(mImageIds[position]); 

     return imageView; 
    } 
} 

public boolean onTouch(View v, MotionEvent event) { 

    if (event.getAction() == MotionEvent.ACTION_MOVE 
      && event.getPointerCount() > 1) { 
     midPoint(mid, event); 

     if(mid.y > start.y){ 

      Log.i(TAG, "Going down (Math.abs(mid.y - start.y)= "+(Math.abs(mid.y - start.y))+" and zoom="+zoom); // going down so increase 
      if ((Math.abs(mid.y - start.y) > 10) && (zoom<2.5f)){ 

       zoom=zoom+0.1f; 
       midPoint(start, event); 
       zoomList(true); 


      } 
      return true; 
     }else if(mid.y < start.y){ 

      Log.i(TAG, "Going up (Math.abs(mid.y - start.y)= "+(Math.abs(mid.y - start.y))+" and zoom="+zoom); //smaller 
      if ((Math.abs(mid.y - start.y) > 10) &&(zoom>0.1)){ 

       midPoint(start, event); 
       zoom=zoom-0.1f; 
       zoomList(false); 

      } 
      return true; 
     } 

    } 

    else if (event.getAction() == MotionEvent.ACTION_POINTER_DOWN) { 
     Log.e(TAG, "Pointer went down: " + event.getPointerCount()); 
     return true; 
    } 
    else if (event.getAction() == MotionEvent.ACTION_UP) { 
     Log.i(TAG, "Pointer going up"); 
     return true; 
    } 
    else if (event.getAction() == MotionEvent.ACTION_DOWN) { 
     Log.i(TAG, "Pointer going down"); 
     start.set(event.getX(), event.getY()); 
     return true; 
    } 

    return false; 
     // indicate event was handled or not 
    } 

private void midPoint(PointF point, MotionEvent event) { 
    float x = event.getX(0) + event.getX(1); 
    float y = event.getY(0) + event.getY(1); 
    point.set(x/2, y/2); 
} 

mi rendo conto che probabilmente dovuto estendere la Galleria o anche un altro gruppo Vista o creare la mia classe, ma non so da dove cominciare: quale metodo utilizzare il responsabile per il ridimensionamento ...

EDIT4: Non so se la domanda è abbastanza chiara. Ecco un esempio di stati:

uno Stato: stato iniziale, abbiamo 3 immagini in vista

Stato 2: si rileva tocchi verticali che vanno in su con 2 dita = Dobbiamo diminuire

Stato 3: iniziamo lo zoom = animazione sulla galleria o sui bambini ???

stato 4: galleria rileva che si tratta di 3 bambini sono più piccoli

stato 5: galleria aggiunge 1/più bambini secondo il nuovo spazio a disposizione

ULTIMO AGGIORNAMENTO: Grazie a tutti coloro che hanno postato, ma ho hanno finalmente raggiunto una conclusione e cioè di non utilizzare Galleria affatto: 1. e 'sconsigliato 2. non è abbastanza personalizzabile per il mio caso

Se si desidera animare diverse immagini in una sola volta che si può prendere in considerazione utilizzando OpenGL , Sto usando biblioteca libgdx: https://github.com/libgdx/libgdx

risposta

4

Il seguente ScalingGallery L'implementazione potrebbe essere d'aiuto.
Questa galleria sottoclasse sovrascrive il getChildStaticTransformation (Bambini, Trasformazione t) metodo in cui viene eseguita la scala.È possibile personalizzare ulteriormente i parametri di ridimensionamento in base alle proprie esigenze.

Si prega di notare la ScalingGalleryItemLayout.java classe. Ciò è necessario perché dopo aver eseguito il funzionamento di ridimensionamento sulle viste secondarie, le relative caselle di controllo non sono più valide e devono essere aggiornate con il metodo getChildStaticTransformation (Visualizza figlio, Trasformazione t).

Questo viene fatto avvolgendo ogni elemento galleria in un ScalingGalleryItemLayout che si estende un LinearLayout. Anche in questo caso, è possibile personalizzarlo per adattarlo alle proprie esigenze se uno LinearLayout non soddisfa le proprie esigenze per il layout degli elementi della galleria.

File: /src/com/example/ScalingGallery.java

/** 
* A Customized Gallery component which alters the size and position of its items based on their position in the Gallery. 
*/ 
public class ScalingGallery extends Gallery { 

    public static final int ITEM_SPACING = -20; 

    private static final float SIZE_SCALE_MULTIPLIER = 0.25f; 
    private static final float ALPHA_SCALE_MULTIPLIER = 0.5f; 
    private static final float X_OFFSET = 20.0f; 

    /** 
    * Implemented by child view to adjust the boundaries after it has been matrix transformed. 
    */ 
    public interface SetHitRectInterface { 
     public void setHitRect(RectF newRect); 
    } 

    /** 
    * @param context 
    *   Context that this Gallery will be used in. 
    * @param attrs 
    *   Attributes for this Gallery (via either xml or in-code) 
    */ 
    public ScalingGallery(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     setStaticTransformationsEnabled(true); 
     setChildrenDrawingOrderEnabled(true); 
    } 

    /** 
    * {@inheritDoc} 
    * 
    * @see #setStaticTransformationsEnabled(boolean) 
    * 
    * This is where the scaling happens. 
    */ 
    protected boolean getChildStaticTransformation(View child, Transformation t) { 

     child.invalidate(); 

     t.clear(); 
     t.setTransformationType(Transformation.TYPE_BOTH); 

     // Position of the child in the Gallery (... +2 +1 0 -1 -2 ... 0 being the middle) 
     final int childPosition = getSelectedItemPosition() - getPositionForView(child); 
     final int childPositionAbs = (int) Math.abs(childPosition); 

     final float left = child.getLeft(); 
     final float top = child.getTop(); 
     final float right = child.getRight(); 
     final float bottom = child.getBottom(); 

     Matrix matrix = t.getMatrix(); 
     RectF modifiedHitBox = new RectF(); 

     // Change alpha, scale and translate non-middle child views. 
     if (childPosition != 0) { 

      final int height = child.getMeasuredHeight(); 
      final int width = child.getMeasuredWidth(); 

      // Scale the size. 
      float scaledSize = 1.0f - (childPositionAbs * SIZE_SCALE_MULTIPLIER); 
      if (scaledSize < 0) { 
       scaledSize = 0; 
      } 
      matrix.setScale(scaledSize, scaledSize); 

      float moveX = 0; 
      float moveY = 0; 

      // Moving from right to left -- linear move since the scaling is done with respect to top-left corner of the view. 
      if (childPosition < 0) { 
       moveX = ((childPositionAbs - 1) * SIZE_SCALE_MULTIPLIER * width) + X_OFFSET; 
       moveX *= -1; 

      } else { // Moving from left to right -- sum of the previous positions' x displacements. 

       // X(n) = X(0) + X(1) + X(2) + ... + X(n-1) 
       for (int i = childPositionAbs; i > 0; i--) { 
        moveX += (i * SIZE_SCALE_MULTIPLIER * width); 
       } 
       moveX += X_OFFSET; 
      } 

      // Moving down y-axis is linear. 
      moveY = ((childPositionAbs * SIZE_SCALE_MULTIPLIER * height)/2); 

      matrix.postTranslate(moveX, moveY); 

      // Scale alpha value. 
      final float alpha = (1.0f/childPositionAbs) * ALPHA_SCALE_MULTIPLIER; 
      t.setAlpha(alpha); 

      // Calculate new hit box. Since we moved the child, the hitbox is no longer lined up with the new child position. 
      final float newLeft = left + moveX; 
      final float newTop = top + moveY; 
      final float newRight = newLeft + (width * scaledSize); 
      final float newBottom = newTop + (height * scaledSize); 
      modifiedHitBox = new RectF(newLeft, newTop, newRight, newBottom); 
     } else { 
      modifiedHitBox = new RectF(left, top, right, bottom); 
     } 

     // update child hit box so you can tap within the child's boundary 
     ((SetHitRectInterface) child).setHitRect(modifiedHitBox); 

     return true; 
    } 

    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 

     // Helps to smooth out jittering during scrolling. 
     // read more - http://www.unwesen.de/2011/04/17/android-jittery-scrolling-gallery/ 
     final int viewsOnScreen = getLastVisiblePosition() - getFirstVisiblePosition(); 
     if (viewsOnScreen <= 0) { 
      super.onLayout(changed, l, t, r, b); 
     } 
    } 

    private int mLastDrawnPosition; 

    @Override 
    protected int getChildDrawingOrder(int childCount, int i) { 

     //Reset the last position variable every time we are starting a new drawing loop 
     if (i == 0) { 
      mLastDrawnPosition = 0; 
     } 

     final int centerPosition = getSelectedItemPosition() - getFirstVisiblePosition(); 

     if (i == childCount - 1) { 
      return centerPosition; 
     } else if (i >= centerPosition) { 
      mLastDrawnPosition++; 
      return childCount - mLastDrawnPosition; 
     } else { 
      return i; 
     } 
    } 
} 

File: /src/com/example/ScalingGalleryItemLayout.java

public class ScalingGalleryItemLayout extends LinearLayout implements SetHitRectInterface { 

    public ScalingGalleryItemLayout(Context context) { 
     super(context); 
    } 

    public ScalingGalleryItemLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public ScalingGalleryItemLayout(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    private Rect mTransformedRect; 

    @Override 
    public void setHitRect(RectF newRect) { 

     if (newRect == null) { 
      return; 
     } 

     if (mTransformedRect == null) { 
      mTransformedRect = new Rect(); 
     } 

     newRect.round(mTransformedRect); 
    } 

    @Override 
    public void getHitRect(Rect outRect) { 

     if (mTransformedRect == null) { 
      super.getHitRect(outRect); 
     } else { 
      outRect.set(mTransformedRect); 
     } 
    } 
} 

File: /res/layout/ScaledGalleryItemLayout.xml

<?xml version="1.0" encoding="utf-8"?> 
<com.example.ScalingGalleryItemLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/gallery_item_layout" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    android:gravity="center" 
    android:orientation="vertical" 
    android:padding="5dp" > 

    <ImageView 
     android:id="@+id/gallery_item_image" 
     android:layout_width="360px" 
     android:layout_height="210px" 
     android:layout_gravity="center" 
     android:antialias="true" 
     android:background="@drawable/gallery_item_button_selector" 
     android:cropToPadding="true" 
     android:padding="35dp" 
     android:scaleType="centerInside" /> 

    <TextView 
     android:id="@+id/gallery_item_text" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:textColor="@drawable/white" 
     android:textSize="30sp" /> 

</com.example.ScalingGalleryItemLayout> 
+0

ringrazia Akos per la tua risposta. L'ho provato ma, mentre uso le animazioni sulla galleria, il risultato è lo stesso di prima: i visibili sono schrinks ma non vengono disegnate nuove viste.Se applico l'animazione a una sola vista quella vista e che solo zooma. Se uso scaleX/scaleY stessa cosa ... Ho deciso di creare la mia Surfaceview e solo disegnare le bitmap – vallllll

+0

Ciao, puoi passare qui il codice completo per favore. – Hasmukh

+0

Per favore metti qui il tuo codice completo ... ne ho bisogno urgentemente ... Grazie in anticipo! –

1

Per mantenere lo stato dell'animazione dopo che è stato fatto, basta fare questo sulla vostra animazione:

youranim.setFillAfter(true); 

Edit:

Nel mio progetto, io uso questo metodo e penso, è aiutare:

http://developer.sonymobile.com/wp/2011/04/12/how-to-take-advantage-of-the-pinch-to-zoom-feature-in-your-xperia%E2%84%A2-10-apps-part-1/

+0

sei rigth ma stavo usando animSet così doveva app lo faccio per tutto il set ma questo non risolve il mio problema: l'animazione riscala la galleria ma non nel modo che voglio. quando la galleria diventa più piccola mi piacerebbe che mostrasse più immagini, ma nel mio caso mostra ancora un'immagine, quindi l'intero layout si riduce appena – vallllll

+0

aggiungo altro metodo – throrin19

+0

sì, ho visto che il codice è ottimo ma ci sono un sacco di esempi là fuori che gestiscono l'ingrandimento del problema è necessario zoomare più immagini contemporaneamente e la Gallery dovrebbe ridimensionarsi per mostrare una o più immagini in base al livello di zoom. – vallllll

0

Questa è la soluzione integrare componente Galleria Android con biblioteca gesto immagine gesture-imageView

E qui è il codice di esempio completo SampleCode

+0

Si prega di non copiare e incollare le risposte tra più domande. Inoltre, le risposte al solo collegamento generalmente sono disapprovate qui, quindi potresti spiegare in maggior dettaglio perché il progetto GitHub collegato risolverà il problema esatto? Infine, preferiremmo che fosse possibile posizionare il codice di esempio da qualche altra parte rispetto a MediaFire, perché quei collegamenti muoiono abbastanza rapidamente. –