今天給大家推薦一個自由拖拽,自由組合的控件报亩,這個控件是我自定義寫的浴鸿。通過它,我們可以自由拖拽弦追,自由組合實(shí)現(xiàn)一個界面岳链,滿足一個用戶自由組合界面的需求。這里不是通過自由拖拽控件劲件,來快速開發(fā)一個界面掸哑,而且更人性化的讓用戶去自由組合一個界面。
前言
最近有一個項目零远,有一個主界面举户,界面上有很多控件或者有多個 fragment 組成,大小不一遍烦,而且由于用戶需要,需要自由拖動和自由組合躺枕,形成用戶自己需要的組合成的模樣服猪。所以就寫了一個 DragerViewLayout ,只要在 DragerViewLayout 下拐云,寫入了多個視圖罢猪,就可以自由拖動和組合了。DragerViewLayout 本質(zhì)上是一個相對布局叉瘩,所以初始位置都可以自己按相對布局的方式來定義膳帕,然后用戶手動拖動后,會自動記錄每個子視圖的位置,進(jìn)行保存危彩,等到重新加載后攒磨,會按照記錄的位置進(jìn)行布局。
效果圖
說一千道一萬汤徽,不如看實(shí)踐娩缰,那就一起來欣賞一下效果圖的效果如何吧?
你們感覺如何?
實(shí)現(xiàn)思路
首先
首先谒府,我們來想想拼坎,要是實(shí)現(xiàn)各個子控件和視圖之間的拖拽和交換位置,那這就意味著所有的子視圖和控件必須在一個層級之內(nèi)完疫,否則跨層級的拖拽是非常難實(shí)現(xiàn)的泰鸡。所以第一個思路就是:
使用相對布局
使用相對布局,其實(shí)可以滿足所有控件都在一個層級之內(nèi)的壳鹤,而且可以滿足我們初始的任何樣式的布局盛龄。況且相對布局是 Android 官方推薦使用的布局。
其次
其次器虾,就該討論拖拽的問題了讯嫂,如何實(shí)現(xiàn)拖拽呢?有沒有更好的兆沙,簡單的方式呢欧芽?難道只能自己實(shí)現(xiàn)觸摸事件,判斷是哪個控件葛圃,計算 X , Y 坐標(biāo)移動呢千扔?非也,其實(shí)有簡單的好辦法库正。那就是:
使用 ViewDragHelper
ViewDragHelper 是一個非常棒的東西曲楚,好用,簡單褥符,不需要你去計算龙誊。2013年谷歌 I/O 大會上介紹了兩個新的 layout: SlidingPaneLayout 和 DrawerLayout,現(xiàn)在這兩個類被廣泛的運(yùn)用喷楣,其實(shí)研究他們的源碼你會發(fā)現(xiàn)這兩個類都運(yùn)用了 ViewDragHelper 來處理拖動趟大。ViewDragHelper 是 framework 中不為人知卻非常有用的一個工具。
ViewDragHelper 解決了 Android 中手勢處理過于復(fù)雜的問題铣焊,在 DrawerLayout 出現(xiàn)之前逊朽,側(cè)滑菜單都是由第三方開源代碼實(shí)現(xiàn)的,其中著名的當(dāng)屬 MenuDrawer 曲伊,MenuDrawer 重寫 onTouchEvent 方法來實(shí)現(xiàn)側(cè)滑效果叽讳,代碼量很大,實(shí)現(xiàn)邏輯也需要很大的耐心才能看懂。如果每個開發(fā)人員都從這么原始的步奏開始做起岛蚤,那對于安卓生態(tài)是相當(dāng)不利的邑狸。所以說 ViewDragHelper 等的出現(xiàn)反映了安卓開發(fā)框架已經(jīng)開始向成熟的方向邁進(jìn)。
關(guān)于 ViewDragHelper 的具體用法灭美,這里不過多贅述推溃,想了解的,在網(wǎng)上一搜届腐,有非常多的文章都在介紹它的基本使用方法铁坎。
再次
再次,我們該如何把拖動的視圖的位置犁苏,保存住呢硬萍?又該如何在重新打開應(yīng)用的時候按照我們自己組合和重新排列的布局顯示呢?其實(shí)方法也一樣很簡單围详,那就是:
記住每個子控件拖拽后的位置朴乖,并保存,在 onLayout 方法中助赞,讀取記錄的位置
在這里买羞,我給每個視圖和控件都增加了一個 tag ,在拖拽的時候根據(jù) tag 知道拖拽的是哪個控件和視圖雹食,然后記錄位置畜普,寫入 SharedPreferences 文件中,在 onLayout 方法中讀取文件群叶,根據(jù)記錄的位置布局吃挑,這樣,再次打開應(yīng)用時街立,就會根據(jù)自己拖拽和組合的方式排列舶衬。
最后
最后,有一個問題就是赎离,相對布局會根據(jù)自己初始的位置有覆蓋層級的逛犹,先寫的在下面,后寫的控件在上面梁剔,拖拽的時候圾浅,怎么把下面的提到上面來呢?方法也很簡單憾朴,那就是:
使用 child.bringToFront() 方法
bringToFront() 方法就是干這個事的,會把操作的視圖喷鸽,提到最上層來众雷。
最后的最后
最后的最后,我就不貼具體的代碼和使用方式了,代碼和使用方法都在我的 github 上砾省,地址如下:
https://github.com/loonggg/DragerViewLayout
有興趣的同學(xué)可以去研究一下鸡岗。