1. 程式人生 > >頁面中可拖拽控制元件的簡單實現方案

頁面中可拖拽控制元件的簡單實現方案

頁面中可拖拽控制元件的簡單實現,可直接一句話實現.

核心程式碼邏輯類如下:

import android.animation.ObjectAnimator;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.DecelerateInterpolator;

/**
 * 控制元件拖動邏輯處理
 * Created by WQ on 2017/10/23.
 */
public class ViewDragMode implements View.OnTouchListener{ private View targetView; public ViewDragMode(final View targetView) { this.targetView=targetView; this.targetView.setOnTouchListener(this); } private int parentHeight; private int parentWidth; private
int lastX; private int lastY; private boolean isDrag; @Override public boolean onTouch(View v, MotionEvent event) { int rawX = (int) event.getRawX(); int rawY = (int) event.getRawY(); switch (event.getAction() & MotionEvent.ACTION_MASK) { case
MotionEvent.ACTION_DOWN: targetView.setPressed(true); isDrag = false; ViewParent viewParent = targetView.getParent(); viewParent.requestDisallowInterceptTouchEvent(true); lastX = rawX; lastY = rawY; ViewGroup parent; parent = (ViewGroup) viewParent; parentHeight = parent.getHeight(); parentWidth = parent.getWidth(); break; case MotionEvent.ACTION_MOVE: if (parentHeight <= 0 || parentWidth == 0) { isDrag = false; break; } else { isDrag = true; } int dx = rawX - lastX; int dy = rawY - lastY; //這裡修復一些華為手機無法觸發點選事件 int distance = (int) Math.sqrt(dx * dx + dy * dy); if (distance == 0) { isDrag = false; break; } float x = targetView.getX() + dx; float y = targetView.getY() + dy; //檢測是否到達邊緣 左上右下 x = x < 0 ? 0 : x > parentWidth - targetView.getWidth() ? parentWidth - targetView.getWidth() : x; y = targetView.getY() < 0 ? 0 : targetView.getY() + targetView.getHeight() > parentHeight ? parentHeight - targetView.getHeight() : y; targetView.setX(x); targetView.setY(y); lastX = rawX; lastY = rawY; break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (!isNotDrag()) { //恢復按壓效果 targetView.setPressed(false); if (rawX >= parentWidth / 2) { //靠右吸附 targetView.animate().setInterpolator(new DecelerateInterpolator()) .setDuration(500) .xBy(parentWidth - targetView.getWidth() - targetView.getX()) .start(); } else { //靠左吸附 ObjectAnimator oa = ObjectAnimator.ofFloat(targetView, "x", targetView.getX(), 0); oa.setInterpolator(new DecelerateInterpolator()); oa.setDuration(500); oa.start(); } } break; } //如果是拖拽則消s耗事件,否則正常傳遞即可。 return !isNotDrag() || targetView.onTouchEvent(event); } /** * 是否拖拽中 * @return */ public boolean isDraging(){ return isDrag; } private boolean isNotDrag() { if(targetView ==null)return true; return !isDrag ; } }

使用方法:

ViewDragMode(targetView)

targetView 為懸浮可拖拽的目標控制元件.實現的效果是,該控制元件可在父容器範圍內進行拖拽,並自動左右吸邊.

該工具類提供isDraging()方法判斷是否處於拖拽中,用於解決一些滑動衝突的問題.