2013-04-23 87 views
0

我的應用程序有一個音樂風琴的背景圖片,我用LinearLayout s和Button s,背景設置爲@null作爲按鍵。Android最佳鋼琴風格佈局

我已經實現我的佈局View.OnTouchListenerOnTouch我在MotionEvent.ACTION_DOWN上播放相關聲音,並在MotionEvent.ACTION_UP上停止播放。

這種工作正常,除了當我滑動我的手指穿過按鈕(器官鍵),由於他們是按鈕(我認爲)沒有新的ontouch事件觸發,除非我擡起和潤飾一個按鈕。

任何人都可以提出一個更好的佈局,使用一些其他的控制,也許這將使我能夠檢測到滑過他們實現向上或向下滑動鍵盤效果?

我真的不想從頭開始畫他們的鑰匙,因爲我想利用比繪製的矩形更令人滿意的背景圖像(用於器官鍵盤)的圖形。 感謝

<LinearLayout android:id="@+id/ll" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/vibrato_off" android:orientation="vertical" android:weightSum="95" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=".main"> 
<LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="70"></LinearLayout> 
<LinearLayout android:id="@+id/llblack" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="11"> 
    <View android:layout_width="1dp" android:layout_height="0dip" android:layout_weight="1.5"/> 
    <android.view.View android:id="@+id/vib_off" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <View android:layout_width="1dp" android:layout_height="0dip" android:layout_weight="0.4"/> 
    <android.view.View android:id="@+id/a2u" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="0.5" android:background="@null"/> 
    <android.view.View android:id="@+id/a2sharp" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/b2u" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="0.5" android:background="@null"/> 
    <android.view.View android:id="@+id/c3u" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="0.5" android:background="@null"/> 
    <android.view.View android:id="@+id/c3sharp" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/d3sharp" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/e3u" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="0.5" android:background="@null"/> 
    <android.view.View android:id="@+id/f3u" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="0.5" android:background="@null"/> 
    <android.view.View android:id="@+id/f3sharp" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/g3sharp" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/a3sharp" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/b3u" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="0.5" android:background="@null"/> 
    <android.view.View android:id="@+id/c4u" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="0.5" android:background="@null"/> 
    <android.view.View android:id="@+id/c4sharp" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/d4sharp" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/e4u" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="0.5" android:background="@null"/> 
    <View android:layout_width="1dp" android:layout_height="0dip" android:layout_weight="0.5"/> 
</LinearLayout> 
<LinearLayout android:id="@+id/llwhite" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="9"> 
    <View android:layout_width="1dp" android:layout_height="0dip" android:layout_weight="1.5"/> 
    <android.view.View android:id="@+id/vib_on" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <View android:layout_width="1dp" android:layout_height="0dip" android:layout_weight="0.4"/> 
    <android.view.View android:id="@+id/a2" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/b2" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/c3" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/d3" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/e3" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/f3" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/g3" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/a3" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/b3" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/c4" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/d4" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <android.view.View android:id="@+id/e4" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@null"/> 
    <View android:layout_width="1dp" android:layout_height="0dip" android:layout_weight="0.4"/> 
</LinearLayout> 

+0

否數學,我使用佈局來確定視圖的位置,直接放置在背景圖像上正確的器官鍵上。我使用佈局權重,以便在不同大小的屏幕上,視圖將覆蓋正確的鍵。你知道一種方法來計算類似的東西,而不使用視圖,而是在整個線性佈局的一些數學,有希望使滑動工作利用action_move? – Mark 2013-04-24 08:35:45

+0

由於非標準音樂鍵盤佈局不是全角,因此很難計算關鍵位置。最後,我保持包含按鈕或視圖的佈局,似乎沒有任何區別,並且在ontouch中,我遍歷所有子視圖,檢查子視圖的觸摸XY到Rect.contains直到匹配。然後使用視圖的標籤,我知道要播放哪個樣本。添加ACTION_MOVE然後克服原來的問題,允許用戶滑過器官鍵。感謝Zabri的幫助。 – Mark 2013-04-24 13:10:58

回答

2

我假設你正在做一些數學知道往哪裏放的按鈕,這樣,他們的記者與背景圖像。

如果設置了OnTouchListener整個LinearLayout並實現它做ACTION_DOWNACTION_UP的東西,你可以用同樣的數學來揣摩出用戶觸摸了LinearLayout知道他或她實際上意在哪個鍵按。所以你根本不需要按鈕。

然後,您將執行偵聽器也在ACTION_MOVE上執行某些操作,並且在您已經在做的數學的幫助下,您可以計算出用戶何時用他或她的手指離開了一個鍵並移動到另一個鍵一。所以你基本上會將當前的手指座標與它的座標進行比較,當以前調用onTouch()方法時,所以你應該知道該移動到了哪個鍵,以便你可以開始播放它的聲音,以及從哪個鍵開始播放你可以停止播放前一個的聲音。如果運動開始並以同一把鑰匙結束,你什麼都不做。

我在一年前做過類似的事情,當時我正在實現一個日曆,用戶可以通過從一個日曆單元格滑動到另一個日曆單元格來選擇間隔。日曆必須隨着用戶的滑動而更新,所以我也必須知道他或她何時離開一個單元並將手指移動到另一個單元。所以我相信,如果你正確地實施它,它會起作用。

我假設,因爲它應該是一個模擬鋼琴的應用程序,您需要允許用戶不僅用一個,而且用兩個(或更多)手指滑動鍵盤,對嗎?我認爲這應該也很容易,因爲MotionEvent帶有關於做動作的指針(手指,鼠標指針......)的信息。我對此沒有任何經驗,但您可以在MotionEvent文檔中閱讀更多關於它的信息:http://developer.android.com/reference/android/view/MotionEvent.html

希望它有幫助。如果您還有其他問題,我很樂意回答(更具體地說 - 我仍然有日曆的代碼)。

祝您好運。

編輯回答評論:

我不是故意使用View!而非Button秒。我的意思是你的佈局只包含一個LinearLayout,背景圖像設置爲它。就是這樣。然後在代碼中,您附加一個OnTouchListener它和onTouch()方法,您計算位置。關於我的頭頂,我認爲你可以這樣做:

我假設應用程序應該用於橫向模式,並且鋼琴的圖像覆蓋整個屏幕。假設你有8個白色鋼琴鍵。通過將屏幕寬度除以8,您可以知道設備上的一個鋼琴鍵的寬度。您還知道一個密鑰從哪裏開始以及結束的位置。假設一個關鍵是50px寬。然後第一個從第一個px開始到第50個結束。第二個從第51個開始,到第100個結束。等等。因此,如果發生觸摸事件,則可以通過調用MotionEvent.getXMotionEvent.getY來訪問其座標。現在我不知道你是否需要getXgetY,你必須弄清楚。因此,我們假設該方法返回一個數字,例如94.當您將它除以先前計算的鋼琴鍵寬度,並將結果四捨五入到最接近的整數時,您就會知道用戶按下了哪個鍵。所以如果寬度是50,你做94/50 = 1.88,四捨五入到2,你有第二把鑰匙。

而且您應該在您的活動中存儲getX/getY變量,以便當您檢測到下一個事件時,您可以知道發生了什麼。所以如果你在第二個鍵上得到ACTION_DOWN,然後你得到ACTION_MOVE並且你計算它實際上已經在第三個鍵上,那麼你知道用戶已經按下第二個鍵然後滑動到第三個鍵。所以你停止播放第二個鍵的聲音並開始播放第三個鍵。

我希望它是有道理的,它不是一個太原始和愚蠢的做法。 :)

+0

好主意,LinearLayout上的OnTouchListener,而不是按鈕...現在要更改代碼..謝謝你提供的信息。 – Mark 2013-04-23 13:45:04

+0

如果它對你有幫助,如果你能接受答案,我也會很高興。謝謝。 – zbr 2013-04-23 19:18:21

+0

當前使用線性佈局中按鈕的位置來確定在ontouch中按下的佈局部分。嘗試了使用整個佈局而不是按鈕的想法,但不能想出一種方法來計算相對於包含器官鍵的背景圖像按下的位置。還嘗試使用視圖而不是按鈕,但MotionEvent.ACTION_MOVE在視圖已被按下時仍未觸發。我會將當前的佈局添加到問題中,以便您瞭解佈局。也許你可能有一個想法如何克服問題... – Mark 2013-04-24 08:31:13