7

您好我正在使用图库小部件来显示从 Internet 下载的图像。

显示几张图像,我希望在人们在屏幕上上下滑动时进行逐渐缩放。我知道如何实现触摸事件唯一我不知道如何使整个画廊视图逐渐增长。我不想放大一张图像我希望整个画廊逐渐放大/缩小。

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

我意识到我可能不得不扩展 Gallery 甚至另一个 View 组或创建我自己的类,但我不知道从哪里开始:哪种方法使用负责缩放的方法......

EDIT4:我不知道他的问题是否足够清楚。以下是状态示例:

状态一:初始状态,我们有 3 张图像在视图中

状态 2:我们检测到 2 个手指向上的垂直触摸 = 我们必须缩小

状态3:我们开始缩放=在画廊或孩子上的动画???

状态 4:画廊检测到它的 3 个孩子更小

状态 5:画廊根据新的可用空间添加 1 个/多个孩子

最后更新:感谢所有发布的内容,但我终于得出了一个结论,那就是根本不使用 Gallery:1. 它已被弃用 2. 对于我的情况,它的可定制性不够

如果您想一次为多个图像设置动画,您可能需要考虑使用 OpenGl,我正在使用 libgdx 库: https ://github.com/libgdx/libgdx

4

4 回答 4

4

以下ScalingGallery实现可能会有所帮助。
此图库子类覆盖执行缩放的getChildStaticTransformation(View child, Transformation t)方法。您可以进一步自定义缩放参数以满足您自己的需要。

请注意ScalingGalleryItemLayout.java类。这是必要的,因为在您对子视图执行缩放操作后,它们的命中框不再有效,因此必须使用getChildStaticTransformation(View child, Transformation 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>
于 2012-07-19T17:42:16.253 回答
1

要在动画完成后保持动画状态,只需对动画执行以下操作:

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-apps-part-1/

于 2012-07-13T10:58:19.033 回答
0

你也可以为画廊做图像缩放捏选项。通过使用以下代码行:

您可以下载示例。

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

我希望这个例子对你有帮助..如果你有任何疑问可以问我.....

于 2012-11-19T07:08:22.213 回答
0

这是将android中的画廊组件与手势图像库 gesture-imageView集成的解决方案

这是完整的示例代码 SampleCode

于 2013-03-24T15:12:44.950 回答