Android Gallery zoom in/out

前端 未结 4 471
北恋
北恋 2020-12-31 20:00

Hi I am using the Gallery widget to show images downloaded from the internet.

to show several images and I would like to have a gradual zoom while people slide up an

4条回答
  •  梦谈多话
    2020-12-31 20:53

    The following ScalingGallery implementation might be of help.
    This gallery subclass overrides the getChildStaticTransformation(View child, Transformation t) method in which the scaling is performed. You can further customize the scaling parameters to fit your own needs.

    Please note the ScalingGalleryItemLayout.java class. This is necessary because after you have performed the scaling operationg on the child views, their hit boxes are no longer valid so they must be updated from with the getChildStaticTransformation(View child, Transformation t) method.

    This is done by wrapping each gallery item in a ScalingGalleryItemLayout which extends a LinearLayout. Again, you can customize this to fit your own needs if a LinearLayout does not meet your needs for layout out your gallery items.

    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

    
    
    
        
    
        
    
    
    

提交回复
热议问题