基於SurfaceView的可拖動視頻控制項

来源:https://www.cnblogs.com/BobGo/archive/2018/03/23/8631514.html
-Advertisement-
Play Games

視頻播放控制項(一) 可拖動,變換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 }

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.shell腳本的方式 index_re.sh sqlplus / as sysdba <<EOFspool /tmp/i.sql repselect 'alter index '||owner||'."'||index_name||'" rebuild;' from dba_indexes wh ...
  • 這幾天有業務部門需要使用一個SAP B1老系統 中的報表,但是由於此報表沒有加時間條件,導致一旦開始查詢 就會導致B1系統異常退出。由於報表對應的SQL 是存在資料庫中,所以想通過查找到這個報表的SQL,然後給SQL加時間條件的方式來處理(多年前的一個報表,不知道內部邏輯,很難重寫)。 但是苦於不清 ...
  • 經過開發和測試環境部署 現在到了我們動手的時候了,萬事開頭難,首先我們實現個小功能 今天我們準備實現這樣一個功能:數據永遠也不會被DELETE掉 ...
  • 一、複製原理 MongoDB的複製功能是使用操作日誌oplog實現的,oplog包含主節點(Master)的每一次寫操作,oplog是local本地資料庫中的一個數據集合,其它非主節點(Secondary)通過讀取主節點的oplog集合中的記錄同步到對應的集合,然後再寫入到自身的local資料庫的o ...
  • 目的 描述鎖定機制以及Oracle如何管理數據併發處理 監視和解決鎖定衝突 鎖 -可防止多個會話同時更改同一數據 -是在指定語句的最低可能級別自動獲取的 -不會升級 事務處理可以鎖定單個數據行,多個數據行,甚至整個表。Oracle DB支持手動鎖定和自動鎖定。自動獲取的鎖總是選擇儘可能低的鎖定級別, ...
  • Oracle資料庫被劃分為稱作表空間的邏輯區域,形成Oracle資料庫的邏輯結構。一個Oracle資料庫對應一個或多個表空間,而一個表空間對應一個或多個物理的資料庫文件。表空間是Oracle資料庫回覆的最小單位,容納著許多資料庫實體,如表、視圖、索引、聚簇、回退段和臨時段等。Oracle資料庫會創建 ...
  • 首先要明確的是,scrollview 其實和普通的 view 並沒有多大的差別,只不過給它加上了一些手勢和約定。 我們知道,要讓一個 scrollview 能夠滾動的方法是設置它的 contentSize 的寬或者高或者同時比自己的 frame 大。 想一想為什麼要這樣做? 首先,scrollvie ...
  • 一、下載模擬器到電腦 夜神模擬器 二、環境配置 電腦--系統--高級系統設置--環境變數 PATH 裡面加入夜神模擬器的安裝目錄下的bin文件 三、啟動模擬器 四、運行cmd命令,cd到夜神安裝目錄(bin目錄下) 命令: 成功結果: 四、Android Studio 運行或調試 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...