ImageView - 放大拉伸或拉下

时间:2015-08-01 12:28:57

标签: android imageview android-imageview image-zoom

如何实现此功能,PullToZoom仅限于ImageView(样本中没有ListView)?

类似question,但没有回答:(

2 个答案:

答案 0 :(得分:2)

使用Gesture Detector怎么样?您可以在以下代码中找到并实现您需要的内容:

public class MainActivity extends AppCompatActivity {

    private static final String DEBUG_TAG = "Gestures";

    private GestureDetectorCompat mDetector;
    private ImageView imageView;
    private MyGestureListener myGestureListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = (ImageView) findViewById(R.id.image);

        myGestureListener = new MyGestureListener();
        mDetector = new GestureDetectorCompat(this, myGestureListener);
        imageView.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                int action = MotionEventCompat.getActionMasked(event);
                if (action == MotionEvent.ACTION_UP) {
                    myGestureListener.upDetected();
                }
                return mDetector.onTouchEvent(event);
            }
        });

        imageView.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.test));

    }

    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {

        private static final float MAX_ZOOM = 0.5f;

        private static final float PCT = 300f;
        private float delta;

        private ValueAnimator valueAnimator;

        @Override
        public boolean onDown(MotionEvent event) {
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            if (valueAnimator != null) {
                valueAnimator.cancel();
            }

            delta += distanceY;
            float pct = getPct(delta);
            imageView.setScaleX(1.0f + pct);
            imageView.setScaleY(1.0f + pct);
            return false;
        }

        void upDetected() {

            float pct = getPct(delta);

            valueAnimator = new ValueAnimator();
            valueAnimator.setFloatValues(pct, 0.0f);
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    imageView.setScaleX(1.0f + (float) animation.getAnimatedValue());
                    imageView.setScaleY(1.0f + (float) animation.getAnimatedValue());
                }
            });
            valueAnimator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    delta = 0f;
                    imageView.setScaleX(1.0f);
                    imageView.setScaleY(1.0f);
                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            });
            valueAnimator.start();
        }

        private float getPct(float delta) {
            float pct = delta / PCT;
            if (pct >= MAX_ZOOM) {
                pct = MAX_ZOOM;
            }
            else if (pct <= -MAX_ZOOM) {
                pct = -MAX_ZOOM;
            }
            return pct;
        }
    }
}

MainActivity有一个简单的ImageView。当您在其中“滚动”时,会检测到手势并缩放图像(向上或向下)。从屏幕上移除手指时,图像将通过简单的动画缩放回原始大小。如果你想避免缩小,你只需要使用getPct()方法。

修改

例如,getPtc可能是这样的(如果您只对放大感兴趣)

private float getPct(float delta) {
    float pct = -delta / PCT;
    if (pct >= MAX_ZOOM) {
        pct = MAX_ZOOM;
    }
    else if (pct <= 0) {
        pct = 0;
    }
    return pct;
}

编辑#2

似乎手势探测器的第一个滚动事件很宽。我添加了一些代码来忽略它

    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {

    private static final float MAX_ZOOM = 0.8f;

    private static final float PCT = 300f;
    private float delta;

    private ValueAnimator valueAnimator;
    private boolean mFirstEvent = true;

    @Override
    public boolean onDown(MotionEvent event) {
        return true;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        if (valueAnimator != null) {
            valueAnimator.cancel();
        }

        if (mFirstEvent) {
            mFirstEvent = false;
            return false;
        }

        delta += distanceY;
        float pct = getPct(delta);
        imageView.setScaleX(1.0f + pct);
        imageView.setScaleY(1.0f + pct);
        textView.setScaleY(1.0f - pct);
        return false;
    }

    void upDetected() {

        mFirstEvent = true;
        float pct = getPct(delta);

        valueAnimator = new ValueAnimator();
        valueAnimator.setFloatValues(pct, 0.0f);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                imageView.setScaleX(1.0f + (Float) animation.getAnimatedValue());
                imageView.setScaleY(1.0f + (Float) animation.getAnimatedValue());
                textView.setScaleY(1.0f - (Float) animation.getAnimatedValue());
            }
        });
        valueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                delta = 0f;
                imageView.setScaleX(1.0f);
                imageView.setScaleY(1.0f);
                textView.setScaleY(1.0f);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        valueAnimator.start();
    }

    private float getPct(float delta) {
        float pct = -delta / PCT;
        if (pct >= MAX_ZOOM) {
            pct = MAX_ZOOM;
        }
        else if (pct <= 0) {
            pct = 0;
        }
        return pct;
    }

    /*private float getPct(float delta) {
        float pct = delta / PCT;
        if (pct >= MAX_ZOOM) {
            pct = MAX_ZOOM;
        }
        else if (pct <= -MAX_ZOOM) {
            pct = -MAX_ZOOM;
        }
        return pct;
    }*/
}

答案 1 :(得分:0)

Android上的Tinder应用程序通过覆盖onTouchEvent()方法来完成类似的功能。查看this帖子了解详情。