2012-07-13 13 views
7

Hola, estoy usando el widget Galería para mostrar las imágenes descargadas de Internet.Android Gallery acercar/alejar

para mostrar varias imágenes y me gustaría tener un zoom gradual mientras las personas se deslizan hacia arriba y hacia abajo en la pantalla. Sé cómo implementar el evento táctil, lo único que no sé es cómo hacer que la vista de la galería crezca gradualmente. No quiero ampliar una imagen. Quiero que la galería se acerque o aleje gradualmente.

EDIT3: Logré hacer zoom en la parte visible de la galería, pero el problema es que necesito encontrar la manera de que la galería lo descubra y actualice también sus otros hijos.

Lo que pasa es que si 3 imágenes son visibles a continuación, se inicia el zoom y la galería se pone más pequeño, también lo hacen las imágenes, pero lo me gustaría en este caso es más imágenes para ser visible pero no sabe cómo para alcanzar este efecto deseado Aquí está el código completo:

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); 
} 

que darse cuenta probablemente voy a tener que ampliar la Galería o incluso otro Ver grupo o crear mi propia clase, pero no sé por dónde empezar: el método que utiliza el responsable de la ampliación ...

EDIT4: No sé si la pregunta es lo suficientemente clara. Aquí está un ejemplo de estados:

un Estado: estado inicial, tenemos 3 imágenes en la vista

Estado 2: detectamos toques verticales que suben con 2 dedos = tenemos que alejar estado

3: comenzamos a hacer zoom = animación en la galería o en los niños ???

estado 4: Galería detecta que se trata de 3 niños son más pequeños

estado 5: galería añade 1/Los niños más de acuerdo con el nuevo espacio disponible

ULTIMA ACTUALIZACION: Gracias a todos los que se han publicado, pero me finalmente haber llegado a una conclusión y que consiste en no utilizar Galería en absoluto: 1. está obsoleto 2. no es lo suficientemente adaptable para mi caso

Si desea animar varias imágenes a la vez es posible que desee considerar el uso de OpenGL , Estoy usando biblioteca libgdx: https://github.com/libgdx/libgdx

Respuesta

4

La siguiente ScalingGallery implementación podría ser de ayuda.
Esta subclase de la galería anula el método getChildStaticTransformation (Ver hijo, Transformación t) en el que se realiza la escala.Puede personalizar aún más los parámetros de escala para satisfacer sus propias necesidades.

Tenga en cuenta la ScalingGalleryItemLayout.java clase. Esto es necesario porque después de haber realizado la operación de escalado en las vistas secundarias, sus recuadros ya no son válidos, por lo que deben actualizarse con el método getChildStaticTransformation (Ver hijo, Transformación t).

Esto se hace envolviendo cada elemento de la galería en un ScalingGalleryItemLayoutcual se extiende un LinearLayout. De nuevo, puede personalizar esto para que se ajuste a sus necesidades si un LinearLayout no satisface sus necesidades de diseño de los elementos de su galería.

del archivo: /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; 
     } 
    } 
} 

del archivo: /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); 
     } 
    } 
} 

del archivo: /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

gracias Akos por su respuesta. Lo he intentado, pero como utilizo animaciones en la galería, el resultado es el mismo que antes: lo visible son enlaces, pero no se dibujan nuevas vistas.Si aplico la animación a una sola vista, esa solo se acerca. Si utilizo scaleX/scaleY lo mismo ... He decidido crear mi propia Surfaceview y simplemente dibujar los mapas de bits – vallllll

+0

Hola, ¿Pueden pasar aquí el código completo, por favor? – Hasmukh

+0

Por favor, ponga su código completo aquí ... lo necesito con urgencia ... ¡Gracias de antemano! –

1

para mantener el estado de la animación después de que se hace esto, simplemente hacer esto por su animación:

youranim.setFillAfter(true); 

Editar:

En mi proyecto, utilizo este método y creo, es ayudarle:

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

estás rigth, pero yo estaba usando AnimSet así que tuvimos que aplicación Esto no resuelve mi problema: la animación vuelve a escalar la galería pero no de la manera que yo quiero. cuando la galería se hace más pequeña, me gustaría que muestre más imágenes, pero en mi caso todavía aparece una imagen, por lo que todo el diseño se contrae – vallllll

+0

agrego otro método – throrin19

+0

sí, he visto ese código, es genial, pero hay muchas ejemplos que manejan el zoom de la imagen el problema es que necesito hacer zoom en varias imágenes al mismo tiempo y la Galería debe redimensionarse para mostrar una o más imágenes de acuerdo con el nivel de zoom. – vallllll

0

Esta es la solución integrar la galería de los componentes de la biblioteca androide con gesto imagen gesture-imageView

Y aquí es código de ejemplo completo SampleCode

+0

No copie y pegue las respuestas en varias preguntas. Además, las respuestas de solo enlaces generalmente son mal vistas aquí, por lo que podría explicar con más detalle por qué el proyecto GitHub vinculado resolverá el problema exacto en cuestión? Finalmente, preferiríamos que pudiera colocar el código de muestra en otro lugar que no fuera MediaFire, porque esos enlaces mueren rápidamente. –

Cuestiones relacionadas