1. 程式人生 > >Android 露珠/水滴 拖拽 效果實現

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