基于SurfaceView的可拖动视频控件
程序员文章站
2022-09-11 14:38:08
视频播放控件(一) 可拖动,变换SurfaceView ......
视频播放控件(一) 可拖动,变换SurfaceView
1 public class DragSurfaceView extends SurfaceView implements View.OnTouchListener { 2 protected int screenWidth; 3 protected int screenHeight; 4 protected int lastX; 5 protected int lastY; 6 private int oriLeft; 7 private int oriRight; 8 private int oriTop; 9 private int oriBottom; 10 private int dragDirection; 11 private static final int TOP = 0x15; 12 private static final int LEFT = 0x16; 13 private static final int BOTTOM = 0x17; 14 private static final int RIGHT = 0x18; 15 private static final int LEFT_TOP = 0x11; 16 private static final int RIGHT_TOP = 0x12; 17 private static final int LEFT_BOTTOM = 0x13; 18 private static final int RIGHT_BOTTOM = 0x14; 19 private static final int CENTER = 0x19; 20 private int offset = 20; 21 22 /** 23 * 初始化获取屏幕宽高 24 */ 25 protected void initScreenW_H() { 26 screenHeight = getResources().getDisplayMetrics().heightPixels - 40; 27 screenWidth = getResources().getDisplayMetrics().widthPixels; 28 Log.i("DragViewTAG", "DragSurfaceView.initScreenW_H: screenWidth="+screenWidth+", screenHeight="+screenHeight); 29 } 30 public DragSurfaceView(Context context) { 31 super(context); 32 setOnTouchListener(this); 33 initScreenW_H(); 34 } 35 36 public DragSurfaceView(Context context, AttributeSet attrs) { 37 super(context, attrs); 38 setOnTouchListener(this); 39 initScreenW_H(); 40 } 41 42 public DragSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { 43 super(context, attrs, defStyleAttr); 44 setOnTouchListener(this); 45 initScreenW_H(); 46 } 47 48 49 @Override 50 public boolean onTouch(View v, MotionEvent event) { 51 int action = event.getAction(); 52 if (action == MotionEvent.ACTION_DOWN) { 53 oriLeft = v.getLeft(); 54 oriRight = v.getRight(); 55 oriTop = v.getTop(); 56 oriBottom = v.getBottom(); 57 lastY = (int) event.getRawY(); 58 lastX = (int) event.getRawX(); 59 dragDirection = getDirection(v, (int) event.getX(), 60 (int) event.getY()); 61 } 62 // 处理拖动事件 63 delDrag(v, event, action); 64 if(action==MotionEvent.ACTION_UP){ 65 dragDirection=0; 66 } 67 invalidate(); 68 return true; 69 } 70 71 72 /** 73 * 获取触摸点flag 74 * 75 * @param v 76 * @param x 77 * @param y 78 * @return 79 */ 80 protected int getDirection(View v, int x, int y) { 81 int left = v.getLeft(); 82 int right = v.getRight(); 83 int bottom = v.getBottom(); 84 int top = v.getTop(); 85 if (x < 40 && y < 40) { 86 return LEFT_TOP; 87 } 88 if (y < 40 && right - left - x < 40) { 89 return RIGHT_TOP; 90 } 91 if (x < 40 && bottom - top - y < 40) { 92 return LEFT_BOTTOM; 93 } 94 if (right - left - x < 40 && bottom - top - y < 40) { 95 return RIGHT_BOTTOM; 96 } 97 if (x < 40) { 98 return LEFT; 99 } 100 if (y < 40) { 101 return TOP; 102 } 103 if (right - left - x < 40) { 104 return RIGHT; 105 } 106 if (bottom - top - y < 40) { 107 return BOTTOM; 108 } 109 return CENTER; 110 } 111 112 /** 113 * 处理拖动事件 114 * 115 * @param v 116 * @param event 117 * @param action 118 */ 119 protected void delDrag(View v, MotionEvent event, int action) { 120 switch (action) { 121 case MotionEvent.ACTION_MOVE: 122 int dx = (int) event.getRawX() - lastX; 123 int dy = (int) event.getRawY() - lastY; 124 switch (dragDirection) { 125 case LEFT: // 左边缘 126 left(v, dx); 127 break; 128 case RIGHT: // 右边缘 129 right(v, dx); 130 break; 131 case BOTTOM: // 下边缘 132 bottom(v, dy); 133 break; 134 case TOP: // 上边缘 135 top(v, dy); 136 break; 137 case CENTER: // 点击中心-->>移动 138 center(v, dx, dy); 139 break; 140 case LEFT_BOTTOM: // 左下 141 left(v, dx); 142 bottom(v, dy); 143 break; 144 case LEFT_TOP: // 左上 145 left(v, dx); 146 top(v, dy); 147 break; 148 case RIGHT_BOTTOM: // 右下 149 right(v, dx); 150 bottom(v, dy); 151 break; 152 case RIGHT_TOP: // 右上 153 right(v, dx); 154 top(v, dy); 155 break; 156 default: 157 break; 158 } 159 v.layout(oriLeft, oriTop, oriRight, oriBottom); 160 // if (dragDirection != CENTER) { 161 // v.layout(oriLeft, oriTop, oriRight, oriBottom); 162 // } 163 lastX = (int) event.getRawX(); 164 lastY = (int) event.getRawY(); 165 Log.i("DragViewTAG", "DragSurfaceView.delDrag:ACTION_MOVE direction="+dragDirection+", left="+oriLeft+", top="+oriTop+", right="+oriRight+", bottom="+oriBottom); 166 break; 167 case MotionEvent.ACTION_UP: 168 ViewGroup.LayoutParams newLayoutParams = getNewLayoutParams(); 169 if(newLayoutParams!=null){ 170 Log.i("DragViewTAG", "DragSurfaceView.delDrag:ACTION_UP width="+newLayoutParams.width+", height="+newLayoutParams.height); 171 setLayoutParams(newLayoutParams); 172 }else { 173 Log.e("DragViewTAG", "DragSurfaceView.delDrag: 父组件类型?"); 174 v.layout(oriLeft, oriTop, oriRight, oriBottom); 175 } 176 break; 177 default: 178 break; 179 } 180 } 181 182 private ViewGroup.LayoutParams getNewLayoutParams(){ 183 if(getLayoutParams() instanceof RelativeLayout.LayoutParams){ 184 RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)getLayoutParams( ); 185 lp.leftMargin = oriLeft; 186 lp.topMargin = oriTop; 187 lp.width = oriRight-oriLeft; 188 lp.height = oriBottom-oriTop; 189 return lp; 190 }else if(getLayoutParams() instanceof FrameLayout.LayoutParams) { 191 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); 192 lp.leftMargin = oriLeft; 193 lp.topMargin = oriTop; 194 lp.width = oriRight - oriLeft; 195 lp.height = oriBottom - oriTop; 196 return lp; 197 } 198 return null; 199 } 200 201 /** 202 * 触摸点为中心->>移动 203 * 204 * @param v 205 * @param dx 206 * @param dy 207 */ 208 private void center(View v, int dx, int dy) { 209 oriLeft += dx; 210 oriTop += dy; 211 oriRight += dx; 212 oriBottom += dy; 213 Log.i("DragViewTAG", "DragSurfaceView.center: v.left="+v.getLeft()+", v.top="+v.getTop()); 214 if (oriLeft < -offset) { 215 Log.e("DragViewTAG", "DragSurfaceView.center: 左侧越界, left="+oriLeft+", offset="+offset); 216 oriLeft = -offset; 217 oriRight = oriLeft + v.getWidth(); 218 } 219 if (oriRight > screenWidth + offset) { 220 Log.e("DragViewTAG", "DragSurfaceView.center: 右侧越界, right="+oriRight+", screenWidth="+screenWidth+", offset="+offset); 221 oriRight = screenWidth + offset; 222 oriLeft = oriRight - v.getWidth(); 223 } 224 if (oriTop < -offset) { 225 Log.e("DragViewTAG", "DragSurfaceView.center: 顶部越界, top="+oriTop+", offset="+offset); 226 oriTop = -offset; 227 oriBottom = oriTop + v.getHeight(); 228 } 229 if (oriBottom > screenHeight + offset) { 230 Log.e("DragViewTAG", "DragSurfaceView.center: 底部越界, bottom="+oriBottom+", screenHeight="+screenHeight+", offset="+offset); 231 oriBottom = screenHeight + offset; 232 oriTop = oriBottom - v.getHeight(); 233 } 234 // v.layout(left, top, right, bottom); 235 236 } 237 238 /** 239 * 触摸点为上边缘 240 * 241 * @param v 242 * @param dy 243 */ 244 private void top(View v, int dy) { 245 oriTop += dy; 246 if (oriTop < -offset) { 247 oriTop = -offset; 248 } 249 if (oriBottom - oriTop - 2 * offset < 200) { 250 oriTop = oriBottom - 2 * offset - 200; 251 } 252 } 253 254 /** 255 * 触摸点为下边缘 256 * 257 * @param v 258 * @param dy 259 */ 260 private void bottom(View v, int dy) { 261 oriBottom += dy; 262 if (oriBottom > screenHeight + offset) { 263 oriBottom = screenHeight + offset; 264 } 265 if (oriBottom - oriTop - 2 * offset < 200) { 266 oriBottom = 200 + oriTop + 2 * offset; 267 } 268 } 269 270 /** 271 * 触摸点为右边缘 272 * 273 * @param v 274 * @param dx 275 */ 276 private void right(View v, int dx) { 277 oriRight += dx; 278 if (oriRight > screenWidth + offset) { 279 oriRight = screenWidth + offset; 280 } 281 if (oriRight - oriLeft - 2 * offset < 200) { 282 oriRight = oriLeft + 2 * offset + 200; 283 } 284 } 285 286 /** 287 * 触摸点为左边缘 288 * 289 * @param v 290 * @param dx 291 */ 292 private void left(View v, int dx) { 293 oriLeft += dx; 294 if (oriLeft < -offset) { 295 oriLeft = -offset; 296 } 297 if (oriRight - oriLeft - 2 * offset < 200) { 298 oriLeft = oriRight - 2 * offset - 200; 299 } 300 } 301 302 /** 303 * 获取截取宽度 304 * 305 * @return 306 */ 307 public int getCutWidth() { 308 return getWidth() - 2 * offset; 309 } 310 311 /** 312 * 获取截取高度 313 * 314 * @return 315 */ 316 public int getCutHeight() { 317 return getHeight() - 2 * offset; 318 } 319 }