Android最佳钢琴风格布局

问题描述:

我的应用程序有一个音乐风琴的背景图片,我用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

我假设你正在做一些数学知道往哪里放的按钮,这样,他们的记者与背景图像。

如果设置了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