欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

基于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 }