Android最佳钢琴风琴布局

时间:2013-04-23 12:04:59

标签: android layout touch piano

我的应用程序有一个音乐风琴的背景图像,我使用了LinearLayoutButton s,其背景设置为@null作为键。

我已使用View.OnTouchListener实现了我的布局,并在OnTouch我在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>

1 个答案:

答案 0 :(得分:2)

我假设你正在做一些数学运算,知道按钮的位置,以便它们与背景图像相对应。

如果您将OnTouchListener设置为整个LinearLayout并将其实施为ACTION_DOWNACTION_UP上的内容,则可以使用相同的数学计算来确定用户已触摸LinearLayout以了解他或她实际要按哪个键。所以你根本不需要按钮。

然后,您将实现侦听器也在ACTION_MOVE上执行某些操作,并且在您已经执行的数学运算的帮助下,您可以确定用户何时用他或她的手指离开了一个键并移动了到另一个。因此,当你先前调用onTouch()方法时,你基本上会将手指的当前坐标与其坐标进行比较,这样你就可以知道移动到哪个键,这样你就可以开始播放它的声音了关键它去了所以你可以停止播放前一个的声音。如果移动在相同的键上开始和结束,则不执行任何操作。

我在一年前做了类似的事情,当时我正在实施一个日历,用户可以通过从一个日历单元格滑动到另一个日历单元格来选择间隔。并且日历必须在用户滑动时更新,因此我还必须知道他或她何时离开一个单元并将手指移动到另一个单元。所以我确信,如果你正确实现它,它将会起作用。

我认为,因为它应该是一个模拟钢琴的应用程序,你需要允许用户不仅用一个,而且用两个(或更多)手指滑动键盘,对吗?我认为这也很容易实现,因为MotionEvent包含有关做动作的指针(手指,鼠标指针......)的信息。我对此没有任何经验,但您可以在MotionEvent文档中了解更多相关信息:http://developer.android.com/reference/android/view/MotionEvent.html

希望它有所帮助。如果您还有其他问题,我很乐意回答(更具体地说 - 我还有日历的代码。)

祝你好运。

编辑回答评论:

我并不是指使用View而不是Button s。我的意思是你的布局只包含LinearLayout,背景图像设置为它。就是这样。然后在代码中,您附加OnTouchListener,并在onTouch()方法中计算位置。我认为你可以这样做:

我认为该应用程序应该以横向模式使用,并且钢琴的图像覆盖整个屏幕。假设你有8个白色钢琴键。通过将屏幕宽度除以8,您可以知道设备上的钢琴键有多宽。您还知道一个键的开始位置和结束位置。假设一个密钥宽50 px。然后第一个从第一个px开始到第50个结束。第二个从第51个开始到第100个结束。等等。

然后,如果触摸事件发生,您可以通过调用MotionEvent.getXMotionEvent.getY来访问其坐标。现在我不知道你是否需要getXgetY,你必须明白这一点。因此,假设该方法返回一个类似于94的数字。当您将其除以先前计算的钢琴键宽度,并将结果四舍五入到最接近的整数时,您将知道用户按下了哪个键。因此,如果宽度为50,则执行94/50 = 1.88,将其四舍五入为2,然后使用第二个键。

您应该在活动中存储getX / getY变量,这样当您检测到下一个事件时,您就可以知道发生了什么。因此,如果您在第二个密钥上获得ACTION_DOWN,然后您得到一个ACTION_MOVE并且您计算它实际上已经在第三个密钥上,您知道用户已经按下第二个密钥然后滑到第三把钥匙。所以你停止播放第二个键的声音并开始播放第三个键。

我希望它有意义,并且它不是一种过于原始和愚蠢的方法。 :)