安卓最好的钢琴风琴布局



我的应用程序有一个音乐风琴的背景图像,我使用LinearLayout s和Button s,它们的背景设置为@null作为键。

我已经实现了我的布局与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>

我想你已经做了一些计算,知道在哪里放置按钮,使它们与背景图像相对应。

如果你将OnTouchListener设置为整个LinearLayout,并实现它在ACTION_DOWNACTION_UP上执行操作,你可以使用相同的数学方法来计算用户触摸LinearLayout的位置,从而知道他或她实际打算按哪个键。所以你根本不需要按钮。

然后你将实现侦听器也在ACTION_MOVE上做一些事情,并在你已经做的数学的帮助下,你可以弄清楚用户何时用他或她的手指离开一个键并移动到另一个键。你基本上会比较手指的当前坐标和之前调用onTouch()方法时的坐标,所以你会知道移动到哪个键,这样你就可以开始播放它的声音,你也会知道它从哪个键开始,这样你就可以停止播放前一个的声音。如果移动的开始和结束在同一个键上,你什么也不做。

我在一年前做过类似的事情,当时我正在实现一个日历,用户可以通过从一个日历单元格滑动到另一个日历单元格来选择一个间隔。而且日历必须在用户滑动时更新,所以我还必须知道他或她什么时候离开一个单元格并将手指移到另一个单元格。所以我敢肯定,如果你正确地实现它,它将工作。

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

希望有帮助。如果你有进一步的问题,我很乐意回答(也更具体-我仍然有日历的代码。)

好运。

编辑回复评论:

我不是说用 Views代替 Buttons。我的意思是你的布局只包括一个LinearLayout与背景图像设置到它。就是这样。然后在代码中,将OnTouchListener附加到它上,并在onTouch()方法中计算位置。我觉得你可以这样做:

我认为应用程序应该在横向模式下使用,钢琴的图像覆盖了整个屏幕。假设上面有8个白色钢琴键。通过将屏幕宽度除以8,你就知道了设备上一个钢琴键的宽度。你也知道一个键在哪里开始,在哪里结束。假设其中一个键的宽度是50px。第一个从第1个px开始到第50个px结束。第二个从51号开始到100号结束。等等。

那么,如果触摸事件发生,你可以通过调用MotionEvent.getXMotionEvent.getY来访问它的坐标。现在我不知道你需要getX还是getY,你必须弄清楚。假设那个方法返回一个数字,比如94。当您将其除以之前计算的钢琴键宽度,并将结果四舍五入到最接近的整数时,您将知道用户按了哪个键。所以如果宽度是50,你可以用94/50 = 1.88,四舍五入到2,你就得到了第二个键。

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

我希望这是有意义的,这不是一个太原始和愚蠢的方法。:)

相关内容

  • 没有找到相关文章

最新更新