在Android图库放大/缩小(Android Gallery zoom in/out)

2019-06-26 06:52发布

嗨,我使用的库部件,显示从互联网上下载的图片。

显示多个图像,我想有一个逐渐放大,而人上下滑动屏幕上。 我知道如何实现触摸事件,我不知道如何使整个画廊视图逐步发展壮大的唯一的事情。 我不想放大一个形象我想整个画廊来放大/缩小逐渐显现。

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

Answer 1:

以下ScalingGallery实现可能的帮助。
这个画廊的子类覆盖getChildStaticTransformation(查看孩子,变换T),在其中进行缩放方法。 您可以进一步自定义缩放参数,以适应自己的需要。

请注意ScalingGalleryItemLayout.java类。 因为你已经进行缩放抗工对孩子意见后,他们的命中框不再有效,使他们必须从与getChildStaticTransformation(查看孩子,变换T)方法来更新这是必要的。

这是由它延伸的LinearLayout一个ScalingGalleryItemLayout包装每家画廊的项目来完成。 同样,你可以自定义此,以适应自己的需要,如果一个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>


Answer 2:

为了保持它完成动画后的状态,只是这样做对你的动画:

youranim.setFillAfter(true);

编辑:

在我的项目,我用这个方法,我认为,它是帮助你:

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应用程式部分-1 /



Answer 3:

U可以为画廊做图片放大捏选项也。 通过使用下面的代码行:

你可以下载的例子。

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

我希望这个例子将有助于u..if u有任何疑问,问我.....



Answer 4:

这是解决在Android中整合图片库元件用手势图像库手势的ImageView

这里是完整的示例代码SampleCode



文章来源: Android Gallery zoom in/out