自定义View通过手势滑动实现了上下左右移动与缩放以及长按的功能

本文详细介绍了如何在Android自定义View中,通过手势识别实现上下左右移动、缩放以及长按功能。在activity中进行相关设置,结合手势库,使用户可以自由地对View进行多方向操作和缩放交互,增强了用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package gbpe.policeass.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.SimpleOnGestureListener;

public class TouchModeView extends View {

   public final static int NONE = 0;
   /**按下*/
   public final static int PRESS = 1;
   /**左移*/
   public final static int LEFT = 2;
   /**右移*/
   public final static int RIGHT = 3;
   /**上移*/
   public final static int UP = 4;
   /**下移*/
   public final static int DOWN = 5;
   /**长按*/
   public final static int LONG_PRESS = 6;
   /**放大*/
   public final static int AMPLIFICATION = 7;
   /**缩小*/
   public final static int NARROW = 8;

   private static final float MIN_MOVE_DISTANCE = 15;

   private  int mTouchMode;
   private float mStartX,mStartY;
   private long mStartTime;
   private float mFingerSpace;

   private GestureDetector mGestureDetector;

   public TouchModeView(Context context) {
      super(context);
      init();
   }

   public TouchModeView(Context context, AttributeSet attrs) {
      super(context, attrs);
      init();
   }

   public TouchModeView(Context context, AttributeSet attrs, int defStyleAttr) {
      super(context, attrs, defStyleAttr);
      init();
   }

   private void init() {
      mGestureDetector = new GestureDetector(getContext(), new MyGestureListener());
   }

   public interface Listener{
      public void getMode(int mode);
   }
   
   Listener mListener;
   
   public void setListener(Listener listener){
      mListener = listener;
   }

   @Override
   public boolean onTouchEvent(MotionEvent event) {
      switch (event.getAction() & MotionEvent.ACTION_MASK) {
      case MotionEvent.ACTION_DOWN:
         mGestureDetector.onTouchEvent(event);
         mTouchMode = PRESS;
         mStartX = event.getRawX();
         mStartY = event.getRawY();
         mStartTime = System.currentTimeMillis();
         mFingerSpace = 0;
         if(mListener !=null){
            mListener.getMode(mTouchMode);
         }
         break;
      case MotionEvent.ACTION_MOVE:
         getGestures(event);
         if(mListener !=null){
            mListener.getMode(mTouchMode);
         }
         break;
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_POINTER_UP:
         mTouchMode = NONE;
         if(mListener !=null){
            mListener.getMode(mTouchMode);
         }
         break;

      case MotionEvent.ACTION_CANCEL:
         mTouchMode = NONE;
         if(mListener !=null){
            mListener.getMode(mTouchMode);
         }
         break;
      }
      return true;
   }


   private void getGestures(MotionEvent event) {
      // 2个手指以上
      if (event.getPointerCount() >= 2){
         //先判断是否是缩放
         float x1 = event.getX(0) - event.getX(1);
         float y1 = event.getY(0) - event.getY(1);
         //第一个手指和第二个手指的间距
         float value = (float) Math.sqrt(x1 * x1 + y1 * y1);
         if(mFingerSpace == 0){
            mFingerSpace = value;
         }else{
            //一段时间内,如果两值间的变化不大,则认为是移动,否则是;加时间限制是为了防止反应过快
            if(System.currentTimeMillis() -mStartTime>50 ){
               //移动后两指的间距的变化值
               float fingerDistanceChange = value - mFingerSpace;
               //同时手指间的间距变化大于最小距离时就认为是缩放
               if(Math.abs(fingerDistanceChange)>MIN_MOVE_DISTANCE){
                  float scale = value / mFingerSpace;
                  if(scale>1){
                     mTouchMode = AMPLIFICATION;
                  }else{
                     mTouchMode = NARROW;
                  }
                  mStartTime = System.currentTimeMillis();
                  mStartX = event.getX();
                  mStartY = event.getY();
                  mFingerSpace = value;
                  //当第一个手指200毫秒内移动MIN_MOVE_DISTANCE倍距离,同时手指间的间距变化小于4倍距离时为移动
               }
            }
            return;
         }
      }
      //判断是否长按,x方向移动小于最小距离同时y方向小于最小距离,
      float offsetX = Math.abs(event.getX() - mStartX);
      float offsetY = Math.abs(event.getY() - event.getY());
      long time = System.currentTimeMillis() - mStartTime;
      if(time>1500&& Math.abs(offsetX)<MIN_MOVE_DISTANCE&&Math.abs(offsetY)<MIN_MOVE_DISTANCE){
         mTouchMode = LONG_PRESS;
         return;
      }

      //移动时 区分上下还是左右
      if(System.currentTimeMillis() -mStartTime>50){
         float xDistance = event.getX() - mStartX;
         float yDistance = event.getY()- mStartY;
         if(Math.abs(xDistance)>Math.abs(yDistance)){
            if(xDistance>0){
               mTouchMode = RIGHT;
            }else{
               mTouchMode = LEFT;
            }
         }else{
            if(yDistance>0){
               mTouchMode = DOWN;
            }else{
               mTouchMode = UP;
            }
         }
         mStartTime = System.currentTimeMillis();
         mStartX = event.getX();
         mStartY = event.getY();
      }
   }


   class MyGestureListener extends SimpleOnGestureListener{
      @Override
      public void onLongPress(MotionEvent e) {
         super.onLongPress(e);
         if(mTouchMode==AMPLIFICATION||mTouchMode==NARROW ){
            return;
         }
         mTouchMode = LONG_PRESS;
         if(mListener !=null){
            mListener.getMode(mTouchMode);
         }
      }
   }

}

 

activity中:

public static final String[] TOUCH_MODE = {"取消","按下","左移","右移","上移","下移","长按","放大","缩小"};
tmv = (TouchModeView) findViewById(R.id.tmv);
tmv.setListener(new TouchModeView.Listener() {
    @Override
    public void getMode(int mode) {
        
        if(mode>TOUCH_MODE.length)return;
        Log.e("mode",mode+"");

        if (TOUCH_MODE[mode].equals("缩小")){
            
        }else if (TOUCH_MODE[mode].equals("放大")){
            
        }else if (TOUCH_MODE[mode].equals("上移")){
           
        }else if (TOUCH_MODE[mode].equals("下移")){
          

        }
    }
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值