您的位置:首页 > 移动开发 > Android开发

Android 图片拖拽、放大缩小的自定义控件

2016-03-18 14:13 309 查看
需求:像相册中的图片跟随手指拖动,双指的放大和缩小,相册中拖出范围之后有弹回的动画,感觉上很圆润,很舒服,我写的例子中并没有加动画

思路:1.自定义DragImageView.java

            2.自定义中先画图片,图片大于屏幕就把图片缩小后显示,图片小于屏幕就直接显示,显示之前要计算显示图片的Rect,Rect是其实就是四个坐标,用来控制显示图片的范                  围,这个Rect是根据图片的长宽比例计算而来,显示在屏幕中间。

            3.跟随手指移动:在touchEvent事件中处理好单双指的各种事件之后,跟随手指就是不断的改变Rect的坐标,然后不断的invalidate()(该方法是重新强制绘制View);

            4.双指缩放:双指缩放的时候从图片Rect的中心缩放的,没有实现相册那种从手指中心缩放的那种。

            5.单指和双指的事件在touc事件中已近处理好了

                   event.getPointerCount()==2的情况就是双指部分

                   float    X0,Y0,X1,Y1双指的四个坐标

                   在双指移动的时候计算一个双指的距离出来m1,在MOVE执行的时候重新计算一个新的距离m2,去判断m1和m2大小来判断双指是张开还是捏合,并且执行相应事件,判断之后把m2复制给m1,这时的MOVE事件会有新的m2出来,所以就一直判断就ok了。放大和缩小就是按照一定的比例去改变Rect的值。

DragImageView.java

[java]
view plain
copy

public class DragImageView extends View {  
  
    private Paint mPaint;  
    private Drawable mDrawable;  
    private Rect mDrawableRect = new Rect();  
    // private Rect mDrawableOffsetRect = new Rect();  
    private Context mContext;  
    private float mRation_WH = 0;  
    private float mOldX = 0;  
    private float mOldY = 0;  
    private float mOldX0, mOldY0, mOldX1, mOldY1, mOldK, mOldB, mOldHandsX,  
            mOldHandsY;  
    private double mD1;  
    private boolean isFirst = true;  
    private int SINGALDOWN = 1;// 单点按下  
    private int MUTILDOWM = 2;// 双点按下  
    private int MUTILMOVE = 3;// 双点拖拽  
    private int mStatus = 0;  
  
    enum STATUS {  
        SINGAL, MUTILDOWN, MUTILMOVE;  
    }  
  
    public DragImageView(Context context) {  
        super(context);  
        this.mContext = context;  
        mPaint = new Paint();  
        mPaint.setAntiAlias(true);  
        mPaint.setColor(Color.BLACK);  
        mPaint.setStyle(Style.FILL);  
        mPaint.setTextSize(35.0f);  
    }  
  
    @SuppressLint("DrawAllocation")  
    @Override  
    protected void onDraw(Canvas canvas) {  
        // TODO Auto-generated method stub  
        super.onDraw(canvas);  
        if (mDrawable == null || mDrawable.getIntrinsicHeight() == 0  
                || mDrawable.getIntrinsicWidth() == 0) {  
            return;  
        }  
        setBounds();  
        mDrawable.draw(canvas);  
        // Log.i("draw", "draw+++++++++++++++++++++++++++++++++++++++");  
  
    }  
  
    @SuppressLint("ClickableViewAccessibility")  
    @Override  
    public boolean onTouchEvent(MotionEvent event) {  
        // TODO Auto-generated method stub  
        switch (event.getPointerCount()) {  
        case 1:  
  
            switch (event.getAction()) {  
            case MotionEvent.ACTION_DOWN:  
                mStatus = SINGALDOWN;  
                mOldX = event.getX();  
                mOldY = event.getY();  
                // Log.i("x_y_down", event.getX() + "__" + event.getY());  
                break;  
            case MotionEvent.ACTION_UP:  
                checkBounds();  
                // Log.i("x_y_up", event.getX() + "__" + event.getY());  
                break;  
            case MotionEvent.ACTION_MOVE:  
                // Log.i("x_y_move", event.getX() + "__" + event.getY());  
                if (mStatus == SINGALDOWN) {  
                    int offsetWidth = (int) (event.getX() - mOldX);  
                    int offsetHeight = (int) (event.getY() - mOldY);  
                    // Log.i("x_y_offset", offsetWidth + "__" + offsetHeight);  
                    mOldX = event.getX();  
                    mOldY = event.getY();  
                    mDrawableRect.offset(offsetWidth, offsetHeight);  
                    invalidate();  
                }  
  
                break;  
            default:  
                break;  
            }  
            break;  
        default:  
            /* 
             * mStatus = MUTILDOWM; if (mStatus == MUTILDOWM) { mOldX0 = 
             * event.getX(0); mOldY0 = event.getY(0); mOldX1 = event.getX(1); 
             * mOldY1 = event.getY(1); mOldK = (mOldY1 - mOldY0) / (mOldX1 - 
             * mOldX0); mOldB = (mOldY0 * mOldX1 - mOldY1 * mOldX0) / (mOldX1 - 
             * mOldX0); mOldHandsX = (mOldX0 + mOldX1) / 2; mOldHandsY = 
             * mOldHandsX * mOldK + mOldB; mD1 = Math.sqrt(Math.pow(mOldX0 - 
             * mOldX1, 2) + Math.pow(mOldY0 - mOldY1, 2)); Log.i("mD1", mD1 + 
             * "________________"); } 
             */  
            switch (event.getAction()) {  
            case MotionEvent.ACTION_POINTER_DOWN:  
                Log.i("DOUBLETOWDOWN", "true");  
                break;  
            case MotionEvent.ACTION_MOVE:  
                // Log.i("x_y_move", event.getX(0) + "__" + event.getY(0) +  
                // "___"  
                // + event.getX(1) + "__" + event.getY(1));  
                mStatus = MUTILMOVE;  
                float X0 = event.getX(0);  
                float Y0 = event.getY(0);  
                float X1 = event.getX(1);  
                float Y1 = event.getY(1);  
                float k = (Y1 - Y0) / (X1 - X0);  
                float b = (Y0 * X1 - Y1 * X0) / (X1 - X0);  
                int RectCenterX = mDrawableRect.centerX();  
                int RectCenterY = mDrawableRect.centerY();  
                float mHandsX = (X0 + X1) / 2;  
                float mHandsY = mHandsX * k + b;  
                double mD2 = Math.sqrt(Math.pow(X0 - X1, 2)  
                        + Math.pow(Y0 - Y1, 2));  
  
                Log.i("GCM", mD2 + "________________X:" + mHandsX + "___Y:"  
                        + mHandsY);  
                if (mD1 < mD2) {  
  
                    // double mMultiple = mD2 / mD1;  
                    // int newWidth = (int) (mDrawableRect.width() * mMultiple);  
                    // int newHeight = (int) (newWidth / mRation_WH);  
                    //  
                    // int newleft = mDrawableRect.left / 2;  
                    // int newtop = mDrawableRect.top / 2;  
                    // int newright = mDrawableRect.right * (3 / 2);  
                    // int newbotto = mDrawableRect.bottom * (3 / 2);  
                    // // mDrawableRect.set(newleft, newtop, newright,  
                    // newbotto);  
                    //  
                    // mDrawableRect.set(RectCenterX - newWidth / 2, RectCenterY  
                    // - newHeight / 2, RectCenterX + newWidth / 2,  
                    // RectCenterY + newHeight / 2);  
                    // invalidate();  
                    if (mDrawableRect.width() < mContext.getResources()  
                            .getDisplayMetrics().widthPixels * 2) {  
                        int offsetwidth = 10;  
                        int offsettop = (int) (offsetwidth / mRation_WH);  
                        mDrawableRect.set(mDrawableRect.left - offsetwidth,  
                                mDrawableRect.top - offsettop,  
                                mDrawableRect.right + offsetwidth,  
                                mDrawableRect.bottom + offsettop);  
                        Log.i("GCM", "aaaaaaaaaaaaaaa");  
  
                        invalidate();  
                    }  
                    // mDrawableRect.offset((int) mHandsX, (int) mHandsY);  
  
                } else {  
                    if (mDrawableRect.width() > mContext.getResources()  
                            .getDisplayMetrics().widthPixels / 3) {  
                        int offsetwidth = 10;  
                        int offsettop = (int) (offsetwidth / mRation_WH);  
                        mDrawableRect.set(mDrawableRect.left + offsetwidth,  
                                mDrawableRect.top + offsettop,  
                                mDrawableRect.right - offsetwidth,  
                                mDrawableRect.bottom - offsettop);  
                        invalidate();  
                        Log.i("GCM", "bbbbbbbbbbbbbbb");  
                    }  
                }  
                mD1 = mD2;  
                if (mHandsX < RectCenterX) {  
                    if (mHandsY < RectCenterY) {  
                        Log.i("PPPPPPP", "1");  
  
                    } else {  
                        Log.i("PPPPPPP", "3");  
                    }  
                } else {  
                    if (mHandsY < RectCenterY) {  
                        Log.i("PPPPPPP", "2");  
                    } else {  
                        Log.i("PPPPPPP", "4");  
                    }  
                }  
  
                //  
  
                break;  
            case MotionEvent.ACTION_UP:  
                Log.i("mStatus", "mutildouble_up");  
                mStatus = 0;  
                break;  
            default:  
                break;  
            }  
            break;  
        }  
  
        return true;  
    }  
  
    public void setBounds() {  
        if (isFirst) {  
            mRation_WH = (float) mDrawable.getIntrinsicWidth()  
                    / (float) mDrawable.getIntrinsicHeight();  
            int px_w = Math.min(getWidth(),  
                    dip2px(mContext, mDrawable.getIntrinsicWidth()));  
            int px_h = (int) (px_w / mRation_WH);  
            int left = (getWidth() - px_w) / 2;  
            int top = (getHeight() - px_h) / 2;  
            int right = px_w + left;  
            int bottom = px_h + top;  
            mDrawableRect.set(left, top, right, bottom);  
            // mDrawableOffsetRect.set(mDrawableRect);  
            isFirst = false;  
            Log.i("rect1______", mDrawableRect.left + "," + mDrawableRect.top  
                    + "," + mDrawableRect.right + "," + mDrawableRect.bottom);  
        }  
        mDrawable.setBounds(mDrawableRect);  
        Log.i("rect2______", mDrawableRect.left + "," + mDrawableRect.top + ","  
                + mDrawableRect.right + "," + mDrawableRect.bottom);  
        Log.i("center_______",  
                mDrawableRect.centerX() + "," + mDrawableRect.centerY());  
  
    }  
  
    public void checkBounds() {  
        int newLeft = mDrawableRect.left;  
        int newTop = mDrawableRect.top;  
        boolean isChange = false;  
        if (newLeft < -mDrawableRect.width()) {  
            newLeft = -mDrawableRect.width();  
            isChange = true;  
        }  
        if (newTop < -mDrawableRect.height()) {  
            newTop = -mDrawableRect.height();  
            isChange = true;  
        }  
        if (newLeft > getWidth()) {  
            newLeft = getWidth();  
            isChange = true;  
        }  
        if (newTop > getHeight()) {  
            newTop = getHeight();  
            isChange = true;  
        }  
        if (isChange) {  
            mDrawableRect.offsetTo(newLeft, newTop);  
            invalidate();  
        }  
    }  
  
    public Drawable getmDrawable() {  
        return mDrawable;  
    }  
  
    public void setmDrawable(Drawable mDrawable) {  
        this.mDrawable = mDrawable;  
    }  
  
    public int dip2px(Context context, int value) {  
        final float scale = context.getResources().getDisplayMetrics().density;  
        return (int) (value * scale + 0.5f);  
    }  
  
}  

在界面中使用

[java]
view plain
copy

public class MainActivity extends Activity {  
  
    Context mContext;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        // TODO Auto-generated method stub  
        super.onCreate(savedInstanceState);  
        this.mContext = getApplicationContext();  
        requestWindowFeature(Window.FEATURE_NO_TITLE);  
        DragImageView mView = new DragImageView(mContext);  
        mView.setmDrawable(mContext.getResources().getDrawable(R.drawable.bbb));  
        setContentView(mView);  
          
    }  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: