在網(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)事件,怎么跳到主布局里面去 .....



想想那種方式似乎實(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;
? ? }
代碼地址: