Android 露珠/水滴 拖拽 效果实现

解释一下标题:

露珠拖拽/水滴拖拽:就是一个View不但能跟着手滑动。还能根据滑动速度,改变形状,像露珠或者水滴那样。

这里是效果实现的Demo

具体实现就是如下一个Java文件 DewdropView.java

package com.demo.dewdropdemo;

import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;


public class DewdropView extends View{
    
    private final String TAG = "dewdrop";
    
    //View的宽和高
    private int width;
    private int height;
    
    //是否正在拖拽
    private boolean isDraging = false;
    
    //手指触摸位置
    private int touchPX;
    private int touchPY;
    
    //上一次统计的位置
    private int mLastX = 0;
    private int mLastY = 0;
    
    //露珠效果大小
    private final int rate = 2;
    
    //要绘制的图片资源
    private Resources mRes;
    private Drawable mDrawable;
    
    //View的位置描述:Left、Top、Right、Bottom
    private int l,t,r,b;
    
    //手机屏幕尺寸
    private int mScrrenWidth;
    private int mScrrenHeight;
    
    public DewdropView(Activity context) {
        super(context);
        // TODO Auto-generated constructor stub
        init(context);
    }
    
    /**
     * @title init
     * @author [email protected]
     * @description TODO 初始化
     * @param context
     * @date 2013-11-05 4:03:05 PM
     */
    private void init(Activity context){
        mRes = context.getResources();
        getScrrenSize(context);
    }
    
    /**
     * @title getScrrenSize
     * @author [email protected]
     * @description TODO 获得手机屏幕大小
     * @param context
     * @date 2013-11-05 4:03:24 PM
     */
    private void getScrrenSize(Activity context){
        DisplayMetrics dm = new DisplayMetrics();
        context.getWindowManager().getDefaultDisplay().getMetrics(dm);
        mScrrenWidth = dm.widthPixels;
        mScrrenHeight = dm.heightPixels;
    }
    
    /**
     * @title setSize
     * @author [email protected]
     * @description TODO 设置View的显示大小
     * @param w
     * @param h
     * @date 2013-11-05 4:03:46 PM
     */
    public void setSize(int w, int h){
        if(w > mScrrenWidth){
            w = mScrrenWidth;
        }
        if(h > mScrrenHeight){
            h = mScrrenHeight;
        }
        width = w;
        height = h;
        r = l + width;
        b = t + height;
        validPos();
    }
    
    /**
     * @title onDraging
     * @author [email protected]
     * @description TODO 拖拽事件处理
     * @date 2013-11-05 4:08:56 PM
     */
    private void onDraging(){
        if(!isDraging){
            return;
        }
        l = touchPX - width/2;
        t = touchPY - height/2;
        r = l + width;
        b = t + height;
        
        int speedX = getSpeedX(touchPX)*rate;
        mLastX = touchPX;
        int speedY = getSpeedY(touchPY)*rate;
        mLastY = touchPY;
        
        boolean isXValid = false;
        if(speedX > speedY){
            isXValid = true;
        }
        
        if(isXValid){
            t = t + speedY;
            b = b - speedY;
            
            l = l - speedX;
            r = r + speedX;
        }else{
            t = t - speedY;
            b = b + speedY;
            
            l = l + speedX;
            r = r - speedX;
        }
        validPos();
        layout(l, t, r, b);
        
    }
    
    /**
     * @title getSpeedX
     * @author [email protected]
     * @description TODO 获得X方向滑动速度
     * @param x
     * @return
     * @date 2013-11-05 4:09:41 PM
     */
    private int getSpeedX(int x){
        if(mLastX == 0){
            return 0;
        }
        return Math.abs(x - mLastX);
    }
    
    /**
     * @title getSpeedY
     * @author [email protected]
     * @description TODO 获得Y方向滑动速度
     * @param y
     * @return
     * @date 2013-11-05 4:10:07 PM
     */
    private int getSpeedY(int y){
        if(mLastY == 0){
            return 0;
        }
        return Math.abs(y - mLastY);
    }
    
    /**
     * @title setImageResource
     * @author [email protected]
     * @description TODO 要显示的图片资源
     * @param id
     * @date 2013-11-05 4:10:28 PM
     */
    public void setImageResource(int id){
        if(mRes != null){
            mDrawable = mRes.getDrawable(id);
        }
    }
    
    /**
     * @title validPos
     * @author [email protected]
     * @description TODO 使得View一直显示在屏幕之内
     * @date 2013-11-04 8:19:51 PM
     */
    private void validPos(){
        if(l < 0){
            l = 0;
            r = width;
        }else if(r > mScrrenWidth){
            r = mScrrenWidth;
            l = r - width;
        }
        
        if(t < 0){
            t = 0;
            b = height;
        }else if(b > mScrrenHeight){
            b = mScrrenHeight;
            t = b - height;
        }
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        if(mDrawable == null) return;
        mDrawable.setBounds(0, 0, getWidth(), getHeight());
        mDrawable.draw(canvas);
    }

    /**
     * @title touch
     * @author [email protected]
     * @description TODO 传递进来的touch事件处理
     * @param event
     * @date 2013-11-05 4:11:20 PM
     */
    public void touch(MotionEvent event) {
        // TODO Auto-generated method stub
        
        touchPX = (int)event.getX();
        touchPY = (int)event.getY();
        
        switch(event.getActionMasked()){
            case MotionEvent.ACTION_DOWN:
                if(isInView()){
                    isDraging = true;
                }
                break;
            case MotionEvent.ACTION_UP:
                isDraging = false;
                if(isInView()){
                    reset();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                onDraging();
                break;
        }
    }
    
    /**
     * @title isInView
     * @author [email protected]
     * @description TODO 判断点击位置是否在此View之上
     * @return
     * @date 2013-11-04 8:17:30 PM
     */
    private boolean isInView(){
        if(touchPX > l && touchPX < r && touchPY > t && touchPY < b){
            return true;
        }
        return false;
    }
    
    /**
     * @title reset
     * @author [email protected]
     * @description TODO 恢复图形正常大小和宽高比
     * @date 2013-11-04 8:16:35 PM
     */
    private void reset(){
        l = touchPX - width/2;
        t = touchPY - height/2;
        r = l + width;
        b = t + height;
        validPos();
        layout(l, t, r, b);
    }

}

具体用法见  效果实现的Demo




猜你喜欢

转载自blog.csdn.net/liu_zhen_wei/article/details/14168827