2012-07-13 6 views
7

Привет, я использую виджет галереи, чтобы показывать изображения, загруженные из Интернета.Android Gallery увеличить/уменьшить

, чтобы показать несколько изображений, и я хотел бы иметь постепенный зум, пока люди скользят вверх и вниз по экрану. Я знаю, как реализовать сенсорное событие, единственное, что я не знаю, как сделать просмотр всей галереи постепенно. Я не хочу увеличивать изображение на одном изображении. Я хочу, чтобы вся галерея постепенно увеличивала/уменьшала масштаб.

EDIT3: Мне удается увеличить видимую часть галереи, но проблема в том, что мне нужно найти способ, чтобы галерея узнала об этом и обновила его и других детей.

Что происходит, если 3 изображения видны, тогда вы начинаете масштабирование, и галерея становится меньше, поэтому изображения, а не то, что Я хотел бы в этом случае больше изображений быть видимыми, но я не знаю, как для достижения желаемого эффекта. Вот весь код:

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

Я понимаю, что, возможно, придется расширить галерею или даже другой вид группы или создать свой собственный класс, но я не знаю, с чего начать: какой метод использовать один отвечает за масштабирование ...

EDIT4: Я не знаю, насколько он достаточно ясен. Ниже приведен пример состояний:

государство один: начальное состояние, у нас есть 3 изображения в поле зрения

Состояние 2: мы обнаруживаем вертикальные штрихи, идущие с 2-мя пальцами = мы должны уменьшить

состояние 3: мы начинаем масштабирование = анимация в галерее или на детях ???

состояние 4: галерея обнаруживает, что это 3-х детей меньше

состояние 5: галерея добавляет 1/больше детей в соответствии с новым свободного пространства

последнее обновление: Спасибо всем, что выложили, но я , наконец, пришли к выводу, и это не использовать галерею на всех: 1. это не рекомендуется 2. это не достаточно настраиваемый для моего случая

Если вы хотите, чтобы оживить несколько изображений сразу вы можете рассмотреть возможность использования OpenGL , Я использую libgdx библиотека: https://github.com/libgdx/libgdx

ответ

4

следующая ScalingGallery реализация может быть полезной.
Этот подкатегория галереи переопределяет getChildStaticTransformation (Просмотреть дочерний элемент, преобразование t) метод, в котором выполняется масштабирование.Вы можете дополнительно настроить параметры масштабирования в соответствии с вашими потребностями.

Пожалуйста, обратите внимание на ScalingGalleryItemLayout.java класс. Это необходимо, потому что после того, как вы выполнили операцию масштабирования g в дочерних представлениях, их метки попадания более недействительны, поэтому их необходимо обновить с помощью getChildStaticTransformation (Просмотреть дочерний элемент, преобразование t).

Это делается путем закручивания каждой галереи пункт в ScalingGalleryItemLayout, который проходит в LinearLayout. Опять же, вы можете настроить это, чтобы оно соответствовало вашим потребностям, если LinearLayout не соответствует вашим потребностям для компоновки элементов вашей галереи.

Файл: /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; 
     } 
    } 
} 

Файл: /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); 
     } 
    } 
} 

Файл: /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

благодарит Akos за ваш ответ. Я пробовал это, но поскольку я использую анимацию в галерее, результат такой же, как и раньше: видимые - это schrinks, но не отображаются новые виды.Если я применил анимацию только к одному представлению, которое будет отображаться, и это только увеличивает масштаб. Если я использую scaleX/scaleY то же самое .... Я решил создать свой собственный Surfaceview и просто нарисовать растровые изображения – vallllll

+0

Здравствуйте, Можете ли вы пройти здесь полный код, пожалуйста. – Hasmukh

+0

Пожалуйста, введите полный код здесь ... Мне нужно срочно ... Спасибо заранее! –

1

Чтобы сохранить состояние анимации после того, как это делается, просто сделать это на анимации:

youranim.setFillAfter(true); 

Edit:

В моем проекте, я использую этот метод и я думаю, это поможет вам:

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

вы Rigth, но я использовал AnimSet так было приложение но это не решает мою проблему: анимация изменяет масштаб галереи, но не так, как я хочу. когда галерея становится меньше, я бы хотел, чтобы она показывала больше изображений, но в моем случае она все еще отображает одно изображение, поэтому весь макет просто сжимается – vallllll

+0

и добавляю другой метод – throrin19

+0

да, я видел этот код, это здорово, но есть много примеры, которые обрабатывают проблему масштабирования изображения, - мне нужно одновременно увеличить несколько изображений, и Галерея должна изменить размер, чтобы показать одно или несколько изображений в соответствии с уровнем масштабирования. – vallllll

0

U может сделать изображение Увеличить вариант пинч для галереи также. , используя приведенные ниже строки кода:

вы можете скачать пример.

https://github.com/alvinsj/android-image-gallery/downloads

Я надеюсь, что этот пример поможет u..if у вас какие-либо запросы спросить меня .....

0

Это решение интеграции галереи компонент в андроида с библиотекой жест-изображения gesture-imageView

а вот полный пример кода SampleCode

+0

Пожалуйста, не копируйте и не вставляйте ответы на несколько вопросов. Кроме того, ссылки на ссылки обычно не одобряются здесь, поэтому вы могли бы объяснить более подробно, почему связанный проект GitHub решит точные проблемы? Наконец, мы предпочли бы, чтобы вы могли разместить образец кода где-то, кроме MediaFire, потому что эти ссылки довольно быстро умирают. –