跨布局拖動(dòng)控件效果

在網(wǎng)上找了很多,沒有找到這種效果,項(xiàng)目中要用到。自己實(shí)現(xiàn)了一套,先看效果圖:

需求:把不同的鍵位拖動(dòng)一起形成確定一個(gè)組合和位置。再把鍵位信息傳給手柄。

分析:鍵位這部分有兩種切換。這個(gè)都都好實(shí)現(xiàn),使用ScrollView ,ListView或者RecylcerView都可以實(shí)現(xiàn)。

主要難點(diǎn)就在于,怎么把控件從,listview里面拖出來放到外面的主布局里面.

上來就遇到了問題:1.當(dāng)拖到listview邊界時(shí)怎么處理,2.滑動(dòng)事件怎么處理,scollview的滑動(dòng)事件,怎么跳到主布局里面去 .....

可以拖動(dòng)到任何位置


點(diǎn)擊清空鍵位回到原來的位置


自定義組合鍵位


想想那種方式似乎實(shí)現(xiàn)不了,又想到的是使用Popuwindow和WindowManager這樣的。直接在界面生成一個(gè)view,不受布局限制。點(diǎn)擊某個(gè)item的時(shí)候,add一個(gè)在界面上,手指移動(dòng)的時(shí)候不斷改變他的坐標(biāo)點(diǎn)。想想就激動(dòng),這好像挺簡(jiǎn)單的,馬上就可以實(shí)現(xiàn),下個(gè)早班了,呵呵^_^。


太惱火了

太惱火了,當(dāng)我做完,準(zhǔn)備關(guān)機(jī)走人的時(shí)候老板來玩了一下,當(dāng)拖動(dòng)兩個(gè)以上出來 ,再進(jìn)行二次拖動(dòng)的時(shí)候問題出來了。這的所在事件都還在第一add的身上。幾個(gè)組合鍵位上百個(gè)按鈕,難道今天晚上要通宵了嗎。可是我還沒有其它的更好思路啊,還是在這個(gè)基礎(chǔ)上解決問題吧,不斷的打輸出日志,打斷點(diǎn)最后認(rèn)為WindowManger不能用來解決這個(gè)問題。

理想很豐滿,現(xiàn)實(shí)很骨感。思路決定出路,格局決定結(jié)局。往往很問題是我們自己想的太復(fù)雜了,搞這些高級(jí)控件。就像我做圓形圖片一樣,老想怎么把它變圓,而沒有想到用一張圓形圖和他疊加在一起,讓人眼只看到圓的那一部分。還不如直接布局里面加控件,Layout不是有addView方法嘛你添加進(jìn)去的每一個(gè)控件,他一定是有事件的。而每當(dāng)按下scrollview里面一個(gè)item的時(shí)候,先隱藏它再到他相同的位置add一個(gè)view而這個(gè)view就是在最上層,這樣就更好實(shí)現(xiàn)拖動(dòng)事件處理了。也更好做還原了remove掉這個(gè)view 再到scollview里面把那個(gè)item顯示出來。

不知道還有沒有更好實(shí)現(xiàn)的方式,歡迎大家指正,討論。

簡(jiǎn)書也坑,這種模式盡然插入不了代碼

按scollview里面item的時(shí)候 addview就加事件:

private FrameLayoutinitFloatButton(Drawable resource, View v) {

? ? ? ? ?floatButtona =new Button(MainActivity.this);

? ? ? ? ?floatButtona.setOnTouchListener(this);

? ? ? ? ?return floatButton;

? ? }

首次移動(dòng)的時(shí)候用scollview里面的touch,因?yàn)槟惆醋〔粍?dòng)事件還在scollview身上

scrollViewChangGui.setOnTouchListener(new View.OnTouchListener() {

@Override

? ? public boolean onTouch(View v, MotionEvent event) {

switch (event.getAction()) {

? ? ? ? ? ? case MotionEvent.ACTION_MOVE:

float x = event.getRawX();

....?

RelativeLayout.LayoutParams layoutParams =new RelativeLayout.LayoutParams(rW, rH);

? ? ? ? ? ? ? ? ? ? ? ? layoutParams.leftMargin = (int) (x );

? ? ? ? ? ? ? ? ? ? ? ? layoutParams.topMargin = (int) (y);

? ? ? ? ? ? ? ? ? ? ? ? listFa.get(listFa.size() -1).setLayoutParams(layoutParams);

? ? ? ? ? ? ? ? ? ? }

}

? ? ? ? ? ? break;

? ? ? ? ? ? case MotionEvent.ACTION_UP:

? ? ? ? ? ? ? ? ? ? ?isUp =false;? scrollEnable =false;

? ? ? ? ? ? break;

? ? ? ? }

? ? ? ? ?return scrollEnable;

? ? }

});

再次移動(dòng)的時(shí)候,事件就在每個(gè)添加進(jìn)來的view自己身上了,

case MotionEvent.ACTION_MOVE:

final float xDistance = event.getX() -downX;

? ? final float yDistance = event.getY() -downY;

? ? if (xDistance !=0 && yDistance !=0) {

int l = (int) (v.getLeft() + xDistance);

? ? ? ? int r = (int) (v.getRight() + xDistance);

? ? ? ? int t = (int) (v.getTop() + yDistance);

? ? ? ? int b = (int) (v.getBottom() + yDistance);

? ? ? ? RelativeLayout.LayoutParams layoutParams =new RelativeLayout.LayoutParams(102, 102);

? ? ? ? layoutParams.leftMargin = l;

? ? ? ? layoutParams.topMargin = t;

? ? ? ? v.setLayoutParams(layoutParams);

break;

? ? }

代碼地址:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容