可移动的ImageView

来源:互联网 发布:库里2016-2017赛季数据 编辑:程序博客网 时间:2024/04/30 12:35

今天做了一个可移动的ImageView,要点如下:

1 ontouch

2 ongloballayout

3 image放置适当的位置

4 matrix变换(平移,缩放)

代码很简单

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">    <com.none.view.MoveImage        android:id="@+id/id_img"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:scaleType="matrix" /></RelativeLayout>
MainActivity.java

package com.none.moveimage;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.widget.ImageView;import com.none.view.MoveImage;public class MainActivity extends ActionBarActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        MoveImage img = (MoveImage)findViewById(R.id.id_img);        img.setImageResource(R.drawable.dou);    }}
MoveImage.java

package com.none.view;import android.content.Context;import android.graphics.Matrix;import android.graphics.RectF;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.view.ViewTreeObserver;import android.widget.ImageView;/** * Created by pc on 2015/5/11. */public class MoveImage extends ImageView implements ViewTreeObserver.OnGlobalLayoutListener, View.OnTouchListener {    private boolean mInit;    private boolean mIsCanMove;    private float mLastX;    private float mLastY;    private Matrix mScaleMatrix;    private int mMoveSlop;    public MoveImage(Context context) {        this(context, null);    }    public MoveImage(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MoveImage(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        mScaleMatrix = new Matrix();        mMoveSlop = ViewConfiguration.get(context).getScaledTouchSlop();        setOnTouchListener(this);        mIsCanMove = false;    }    @Override    protected void onAttachedToWindow() {        getViewTreeObserver().addOnGlobalLayoutListener(this);    }    @Override    protected void onDetachedFromWindow() {        getViewTreeObserver().removeOnGlobalLayoutListener(this);    }    @Override    public void onGlobalLayout() {        if (!mInit) {            Drawable d = getDrawable();            if (d != null) {                float scale = 1.0f;                int dw = d.getIntrinsicWidth();                int dh = d.getIntrinsicHeight();                int width = getWidth();                int height = getHeight();                if (dw > width && dh < height) {                    scale = width * 1.0f / dw;                } else if (dw < width && dh > height) {                    scale = height * 1.0f / dh;                } else if (dw < width && dh < height) {                    scale = Math.min(width * 1.0f / dw, height * 1.0f / dh);                } else if (dw > width && dh > height) {                    scale = Math.min(width * 1.0f / dw, height * 1.0f / dh);                } else {                    scale = 1.0f;                }                int centerX = (width - dw) / 2;                int centerY = (height - dh) / 2;                mScaleMatrix.postTranslate(centerX, centerY);                scale = scale / 2.0f;                mScaleMatrix.postScale(scale, scale, width / 2, height / 2);                setImageMatrix(mScaleMatrix);            }        }        mInit = true;    }    private RectF getMatrixRectF() {        RectF rectf = new RectF();        final Matrix matrix = mScaleMatrix;        Drawable d = getDrawable();        if (d != null) {            rectf.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());            matrix.mapRect(rectf);        }        return rectf;    }    private boolean isMoveAction(float dx, float dy) {        return Math.sqrt(dx * dx + dy * dy) > mMoveSlop;    }    @Override    public boolean onTouch(View v, MotionEvent event) {        RectF rectF = getMatrixRectF();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                mLastX = event.getX();                mLastY = event.getY();                mIsCanMove = rectF.contains(mLastX, mLastY);                break;            case MotionEvent.ACTION_MOVE:                if (mIsCanMove) {                    float x = event.getX();                    float y = event.getY();                    float deltaX = x - mLastX;                    float deltaY = y - mLastY;                    if (isMoveAction(deltaX, deltaY)) {                        checkBorderWhenMove(deltaX, deltaY, rectF);                        setImageMatrix(mScaleMatrix);                    }                    mLastX = x;                    mLastY = y;                }                break;            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_CANCEL:                mIsCanMove = false;                break;        }        return true;    }    private void checkBorderWhenMove(float deltaX, float deltaY, RectF rectF) {        int width = getWidth();        int height = getHeight();        if (rectF.left + deltaX < 0) {            deltaX = -rectF.left;        } else if (rectF.right + deltaX > width) {            deltaX = width - rectF.right;        }        if (rectF.top + deltaY < 0) {            deltaY = -rectF.top;        } else if (rectF.bottom + deltaY > height) {            deltaY = height - rectF.bottom;        }        mScaleMatrix.postTranslate(deltaX, deltaY);    }}

其中图片缩放使用了matrix方式,在xml中需要将imageview的scale方式设置为matrix。

之后在根据ongloballayout中的得到的图片size和屏幕大小进行比例计算,之后使用matrix.postscale对图片进行缩放。

图片的平移使用了matrix.posttranslate,平移的距离可随意指定。

另外还需要获得每次缩放后图片的rectf,也就是图片当前的位置。这个可以使用matrix.maprect获得。

最后在ontouch中控制图片的平移,在Down中对触摸点进行判断,非图片的点击不会对图片产生影响,当点击的是图片时,使用setimagematrix对图片移动进行刷新。

在移动的过程中判断图片是否会移动出屏幕,对上下左右进行判断,防止图片移动出屏幕。


参考http://www.imooc.com/learn/239中对图片伸缩和伸缩和的上下左右位置的处理。



0 0
原创粉丝点击