当前位置: 首页 > 编程笔记 >

基于SurfaceView实现可拖动视频控件

吴弘壮
2023-03-14
本文向大家介绍基于SurfaceView实现可拖动视频控件,包括了基于SurfaceView实现可拖动视频控件的使用技巧和注意事项,需要的朋友参考一下

本文实例为大家分享了基于SurfaceView的可拖动视频控件,供大家参考,具体内容如下

public class DragSurfaceView extends SurfaceView implements View.OnTouchListener {
 protected int screenWidth;
 protected int screenHeight;
 protected int lastX;
 protected int lastY;
 private int oriLeft;
 private int oriRight;
 private int oriTop;
 private int oriBottom;
 private int dragDirection;
 private static final int TOP = 0x15;
 private static final int LEFT = 0x16;
 private static final int BOTTOM = 0x17;
 private static final int RIGHT = 0x18;
 private static final int LEFT_TOP = 0x11;
 private static final int RIGHT_TOP = 0x12;
 private static final int LEFT_BOTTOM = 0x13;
 private static final int RIGHT_BOTTOM = 0x14;
 private static final int CENTER = 0x19;
 private int offset = 20;

 /**
  * 初始化获取屏幕宽高
  */
 protected void initScreenW_H() {
  screenHeight = getResources().getDisplayMetrics().heightPixels - 40;
  screenWidth = getResources().getDisplayMetrics().widthPixels;
  Log.i("DragViewTAG", "DragSurfaceView.initScreenW_H: screenWidth="+screenWidth+", screenHeight="+screenHeight);
 }
 public DragSurfaceView(Context context) {
  super(context);
  setOnTouchListener(this);
  initScreenW_H();
 }

 public DragSurfaceView(Context context, AttributeSet attrs) {
  super(context, attrs);
  setOnTouchListener(this);
  initScreenW_H();
 }

 public DragSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  setOnTouchListener(this);
  initScreenW_H();
 }


 @Override
 public boolean onTouch(View v, MotionEvent event) {
  int action = event.getAction();
  if (action == MotionEvent.ACTION_DOWN) {
   oriLeft = v.getLeft();
   oriRight = v.getRight();
   oriTop = v.getTop();
   oriBottom = v.getBottom();
   lastY = (int) event.getRawY();
   lastX = (int) event.getRawX();
   dragDirection = getDirection(v, (int) event.getX(),
     (int) event.getY());
  }
  // 处理拖动事件
  delDrag(v, event, action);
  if(action==MotionEvent.ACTION_UP){
   dragDirection=0;
  }
  invalidate();
  return true;
 }


 /**
  * 获取触摸点flag
  *
  * @param v
  * @param x
  * @param y
  * @return
  */
 protected int getDirection(View v, int x, int y) {
  int left = v.getLeft();
  int right = v.getRight();
  int bottom = v.getBottom();
  int top = v.getTop();
  if (x < 40 && y < 40) {
   return LEFT_TOP;
  }
  if (y < 40 && right - left - x < 40) {
   return RIGHT_TOP;
  }
  if (x < 40 && bottom - top - y < 40) {
   return LEFT_BOTTOM;
  }
  if (right - left - x < 40 && bottom - top - y < 40) {
   return RIGHT_BOTTOM;
  }
  if (x < 40) {
   return LEFT;
  }
  if (y < 40) {
   return TOP;
  }
  if (right - left - x < 40) {
   return RIGHT;
  }
  if (bottom - top - y < 40) {
   return BOTTOM;
  }
  return CENTER;
 }

 /**
  * 处理拖动事件
  *
  * @param v
  * @param event
  * @param action
  */
 protected void delDrag(View v, MotionEvent event, int action) {
  switch (action) {
   case MotionEvent.ACTION_MOVE:
    int dx = (int) event.getRawX() - lastX;
    int dy = (int) event.getRawY() - lastY;
    switch (dragDirection) {
     case LEFT: // 左边缘
      left(v, dx);
      break;
     case RIGHT: // 右边缘
      right(v, dx);
      break;
     case BOTTOM: // 下边缘
      bottom(v, dy);
      break;
     case TOP: // 上边缘
      top(v, dy);
      break;
     case CENTER: // 点击中心-->>移动
      center(v, dx, dy);
      break;
     case LEFT_BOTTOM: // 左下
      left(v, dx);
      bottom(v, dy);
      break;
     case LEFT_TOP: // 左上
      left(v, dx);
      top(v, dy);
      break;
     case RIGHT_BOTTOM: // 右下
      right(v, dx);
      bottom(v, dy);
      break;
     case RIGHT_TOP: // 右上
      right(v, dx);
      top(v, dy);
      break;
     default:
      break;
    }
    v.layout(oriLeft, oriTop, oriRight, oriBottom);
//    if (dragDirection != CENTER) {
//     v.layout(oriLeft, oriTop, oriRight, oriBottom);
//    }
    lastX = (int) event.getRawX();
    lastY = (int) event.getRawY();
    Log.i("DragViewTAG", "DragSurfaceView.delDrag:ACTION_MOVE direction="+dragDirection+", left="+oriLeft+", top="+oriTop+", right="+oriRight+", bottom="+oriBottom);
    break;
   case MotionEvent.ACTION_UP:
    ViewGroup.LayoutParams newLayoutParams = getNewLayoutParams();
    if(newLayoutParams!=null){
     Log.i("DragViewTAG", "DragSurfaceView.delDrag:ACTION_UP width="+newLayoutParams.width+", height="+newLayoutParams.height);
     setLayoutParams(newLayoutParams);
    }else {
     Log.e("DragViewTAG", "DragSurfaceView.delDrag: 父组件类型?");
     v.layout(oriLeft, oriTop, oriRight, oriBottom);
    }
    break;
   default:
    break;
  }
 }

 private ViewGroup.LayoutParams getNewLayoutParams(){
  if(getLayoutParams() instanceof RelativeLayout.LayoutParams){
   RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)getLayoutParams( );
   lp.leftMargin = oriLeft;
   lp.topMargin = oriTop;
   lp.width = oriRight-oriLeft;
   lp.height = oriBottom-oriTop;
   return lp;
  }else if(getLayoutParams() instanceof FrameLayout.LayoutParams) {
   FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
   lp.leftMargin = oriLeft;
   lp.topMargin = oriTop;
   lp.width = oriRight - oriLeft;
   lp.height = oriBottom - oriTop;
   return lp;
  }
  return null;
 }

 /**
  * 触摸点为中心->>移动
  *
  * @param v
  * @param dx
  * @param dy
  */
 private void center(View v, int dx, int dy) {
  oriLeft += dx;
  oriTop += dy;
  oriRight += dx;
  oriBottom += dy;
  Log.i("DragViewTAG", "DragSurfaceView.center: v.left="+v.getLeft()+", v.top="+v.getTop());
  if (oriLeft < -offset) {
   Log.e("DragViewTAG", "DragSurfaceView.center: 左侧越界, left="+oriLeft+", offset="+offset);
   oriLeft = -offset;
   oriRight = oriLeft + v.getWidth();
  }
  if (oriRight > screenWidth + offset) {
   Log.e("DragViewTAG", "DragSurfaceView.center: 右侧越界, right="+oriRight+", screenWidth="+screenWidth+", offset="+offset);
   oriRight = screenWidth + offset;
   oriLeft = oriRight - v.getWidth();
  }
  if (oriTop < -offset) {
   Log.e("DragViewTAG", "DragSurfaceView.center: 顶部越界, top="+oriTop+", offset="+offset);
   oriTop = -offset;
   oriBottom = oriTop + v.getHeight();
  }
  if (oriBottom > screenHeight + offset) {
   Log.e("DragViewTAG", "DragSurfaceView.center: 底部越界, bottom="+oriBottom+", screenHeight="+screenHeight+", offset="+offset);
   oriBottom = screenHeight + offset;
   oriTop = oriBottom - v.getHeight();
  }
//  v.layout(left, top, right, bottom);

 }

 /**
  * 触摸点为上边缘
  *
  * @param v
  * @param dy
  */
 private void top(View v, int dy) {
  oriTop += dy;
  if (oriTop < -offset) {
   oriTop = -offset;
  }
  if (oriBottom - oriTop - 2 * offset < 200) {
   oriTop = oriBottom - 2 * offset - 200;
  }
 }

 /**
  * 触摸点为下边缘
  *
  * @param v
  * @param dy
  */
 private void bottom(View v, int dy) {
  oriBottom += dy;
  if (oriBottom > screenHeight + offset) {
   oriBottom = screenHeight + offset;
  }
  if (oriBottom - oriTop - 2 * offset < 200) {
   oriBottom = 200 + oriTop + 2 * offset;
  }
 }

 /**
  * 触摸点为右边缘
  *
  * @param v
  * @param dx
  */
 private void right(View v, int dx) {
  oriRight += dx;
  if (oriRight > screenWidth + offset) {
   oriRight = screenWidth + offset;
  }
  if (oriRight - oriLeft - 2 * offset < 200) {
   oriRight = oriLeft + 2 * offset + 200;
  }
 }

 /**
  * 触摸点为左边缘
  *
  * @param v
  * @param dx
  */
 private void left(View v, int dx) {
  oriLeft += dx;
  if (oriLeft < -offset) {
   oriLeft = -offset;
  }
  if (oriRight - oriLeft - 2 * offset < 200) {
   oriLeft = oriRight - 2 * offset - 200;
  }
 }

 /**
  * 获取截取宽度
  *
  * @return
  */
 public int getCutWidth() {
  return getWidth() - 2 * offset;
 }

 /**
  * 获取截取高度
  *
  * @return
  */
 public int getCutHeight() {
  return getHeight() - 2 * offset;
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍Android基于widget组件实现物体移动/控件拖动功能示例,包括了Android基于widget组件实现物体移动/控件拖动功能示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Android基于widget组件实现物体移动/控件拖动功能。分享给大家供大家参考,具体如下: 更多关于Android相关内容感兴趣的读者可查看本站专题:《Android基本组件用法总结》、《A

  • 本文向大家介绍Android编程之控件可拖动的实现方法,包括了Android编程之控件可拖动的实现方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Android编程之控件可拖动的实现方法。分享给大家供大家参考,具体如下: 点击和触摸的区别是什么? 点击: 一组动作的集合 手指按下着按钮 手指要在按钮停留一段时间 手指离开按钮 xml如下: 触摸: 手指一挨着屏幕 手指移动 手指离开屏幕

  • 本文向大家介绍基于Vue实现拖拽功能,包括了基于Vue实现拖拽功能的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Vue实现拖拽功能的具体代码,供大家参考,具体内容如下 效果图: HTML代码: JS代码: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 本文向大家介绍基于Vue实现拖拽效果,包括了基于Vue实现拖拽效果的使用技巧和注意事项,需要的朋友参考一下 效果图   demo1.gif 分清clientY pageY screenY layerY offsetY的区别 在我们想要做出拖拽这个效果的时候,我们需要分清这几个属性的区别,这几个属性都是计算鼠标点击的偏移值,我们需要对其进行了解才可以继续实现我们的拖拽效果 clientY 指的是距离

  • 我已经创建了一个媒体播放器,它在表面视图上播放视频。视频完成后,视频的最后一帧仍保留在表面上。我想从表面移除视频帧,因为经过一些延迟后,另一个视频开始。 谁能帮助解决这个问题。 谢谢山贾因

  • 本文向大家介绍基于python爬取梨视频实现过程解析,包括了基于python爬取梨视频实现过程解析的使用技巧和注意事项,需要的朋友参考一下 目标网址:梨视频 然后我们找到科技这一页:https://www.pearvideo.com/category_8。其实你要哪一页都行,你喜欢就行。嘿嘿… 这是动态网站,所以咱们直奔network 然后去到XHR: 找规律,这个应该不难,我就直接贴网址上来咯,