一個可拖拽,移動,自由組合子控制元件的檢視控制元件,讓開發更簡單

澀郎發表於2019-02-27

今天給大家推薦一個自由拖拽,自由組合的控制元件,這個控制元件是我自定義寫的。通過它,我們可以自由拖拽,自由組合實現一個介面,滿足一個使用者自由組合介面的需求。這裡不是通過自由拖拽控制元件,來快速開發一個介面,而且更人性化的讓使用者去自由組合一個介面。

前言

最近有一個專案,有一個主介面,介面上有很多控制元件或者有多個 fragment 組成,大小不一,而且由於使用者需要,需要自由拖動和自由組合,形成使用者自己需要的組合成的模樣。所以就寫了一個 DragerViewLayout ,只要在 DragerViewLayout 下,寫入了多個檢視,就可以自由拖動和組合了。DragerViewLayout 本質上是一個相對佈局,所以初始位置都可以自己按相對佈局的方式來定義,然後使用者手動拖動後,會自動記錄每個子檢視的位置,進行儲存,等到重新載入後,會按照記錄的位置進行佈局。

效果圖

說一千道一萬,不如看實踐,那就一起來欣賞一下效果圖的效果如何吧?

一個可拖拽,移動,自由組合子控制元件的檢視控制元件,讓開發更簡單

一個可拖拽,移動,自由組合子控制元件的檢視控制元件,讓開發更簡單

你們感覺如何?

實現思路

首先

首先,我們來想想,要是實現各個子控制元件和檢視之間的拖拽和交換位置,那這就意味著所有的子檢視和控制元件必須在一個層級之內,否則跨層級的拖拽是非常難實現的。所以第一個思路就是:

使用相對佈局

使用相對佈局,其實可以滿足所有控制元件都在一個層級之內的,而且可以滿足我們初始的任何樣式的佈局。況且相對佈局是 Android 官方推薦使用的佈局。

其次

其次,就該討論拖拽的問題了,如何實現拖拽呢?有沒有更好的,簡單的方式呢?難道只能自己實現觸控事件,判斷是哪個控制元件,計算 X , Y 座標移動呢?非也,其實有簡單的好辦法。那就是:

使用 ViewDragHelper

ViewDragHelper 是一個非常棒的東西,好用,簡單,不需要你去計算。2013年穀歌 I/O 大會上介紹了兩個新的 layout: SlidingPaneLayout 和 DrawerLayout,現在這兩個類被廣泛的運用,其實研究他們的原始碼你會發現這兩個類都運用了 ViewDragHelper 來處理拖動。ViewDragHelper 是 framework 中不為人知卻非常有用的一個工具。

ViewDragHelper 解決了 Android 中手勢處理過於複雜的問題,在 DrawerLayout 出現之前,側滑選單都是由第三方開原始碼實現的,其中著名的當屬 MenuDrawer ,MenuDrawer 重寫 onTouchEvent 方法來實現側滑效果,程式碼量很大,實現邏輯也需要很大的耐心才能看懂。如果每個開發人員都從這麼原始的步奏開始做起,那對於安卓生態是相當不利的。所以說 ViewDragHelper 等的出現反映了安卓開發框架已經開始向成熟的方向邁進。

關於 ViewDragHelper 的具體用法,這裡不過多贅述,想了解的,在網上一搜,有非常多的文章都在介紹它的基本使用方法。

再次

再次,我們該如何把拖動的檢視的位置,儲存住呢?又該如何在重新開啟應用的時候按照我們自己組合和重新排列的佈局顯示呢?其實方法也一樣很簡單,那就是:

記住每個子控制元件拖拽後的位置,並儲存,在 onLayout 方法中,讀取記錄的位置

在這裡,我給每個檢視和控制元件都增加了一個 tag ,在拖拽的時候根據 tag 知道拖拽的是哪個控制元件和檢視,然後記錄位置,寫入 SharedPreferences 檔案中,在 onLayout 方法中讀取檔案,根據記錄的位置佈局,這樣,再次開啟應用時,就會根據自己拖拽和組合的方式排列。

最後

最後,有一個問題就是,相對佈局會根據自己初始的位置有覆蓋層級的,先寫的在下面,後寫的控制元件在上面,拖拽的時候,怎麼把下面的提到上面來呢?方法也很簡單,那就是:

使用 child.bringToFront() 方法

bringToFront() 方法就是幹這個事的,會把操作的檢視,提到最上層來。

最後的最後

最後的最後,我就不貼具體的程式碼和使用方式了,程式碼和使用方法都在我的 github 上,地址如下:

github.com/loonggg/Dra…

有興趣的同學可以去研究一下,或者歡迎關注我的微信公眾號來跟我一起交流技術,加群一起分享學習。

歡迎大家關注我的技術分享公眾號:非著名程式設計師(smart_android)。技術文章均先首發於我的技術分享的微信公眾號。

一個可拖拽,移動,自由組合子控制元件的檢視控制元件,讓開發更簡單

相關文章