简体   繁体   English

OntouchListener跨按钮拖动

[英]OntouchListener drag across buttons

I am developing a piano app for android. 我正在为Android开发钢琴应用程序。 I am trying to implement OnTouchListener for all the 8 buttons that I have in my activity. 我正在尝试为我的活动中的所有8个按钮实现OnTouchListener So, when the user drags or swipes his finger I want all the buttons to play the sound. 因此,当用户拖动或滑动手指时,我希望所有按钮都可以播放声音。 I think the picture below explains it better. 我认为下面的图片可以更好地说明这一点。

See? 看到? When the user will place his hand on the first button and then drag till the last button, I want all the 8 buttons to play the song. 当用户将手放在第一个按钮上然后拖动到最后一个按钮时,我希望所有8个按钮都可以播放歌曲。 But I am not able to achieve it. 但是我无法实现。 The below java code works only for the first button but the rest of the 7 buttons don't get pressed. 下面的Java代码仅适用于第一个按钮,但其余7个按钮没有被按下。

Here it is: 这里是:

@Override
public boolean onTouch(View v, MotionEvent event) {
    switch(v.getID())
    {
        case(R.id.btn1):
        //play button 1 sound
        break;

        case(R.id.btn2):
        //play button 2 sound
        break;

        case(R.id.btn3):
        //play button 3 sound
        break;

        case(R.id.btn4):
        //play button 4 sound
        break;

        case(R.id.btn5):
        //play button 1 sound
        break;

        case(R.id.btn6):
        //play button 6 sound
        break;

        case(R.id.btn7):
        //play button 7 sound
        break;

        case(R.id.btn8):
        //play button 8 sound
        break;
        }          
    return true;
    }

I have already seen this question and this as well but couldn't find an answer there. 我已经看到了这个问题, 很好,但无法找到一个答案出现。

Please help me out. 请帮帮我。 Thank you for you time! 谢谢您的时间!

You should implement onTouchListner on the layout which contains the piano buttons 您应该在包含钢琴按钮的布局上实现onTouchListner

The idea is to get all piano buttons positions on the screen (x , y) after render them. 想法是在渲染所有钢琴按钮后将它们显示在屏幕上(x,y)。

then get touch position by using getX() and getY() methods. 然后使用getX()和getY()方法获取触摸位置。

At this point you can handle it by checking if the touch x and y is between the view start and 此时,您可以通过检查触摸x和y是否在视图开始和

end x and y, then play the sound of the view. 结束x和y,然后播放视图声音。

At this example i'am using soundpool and pitch to play different sounds (i know that it's not the perfect way), and i'm also working on x factor only because i'm using piano white keys only. 在此示例中,我正在使用音池和音高播放不同的声音(我知道这不是理想的方式),并且我也正在研究x因子,因为我仅在使用钢琴白键。

import android.app.Activity;
import android.media.*;
import android.os.Bundle;
import android.view.*;
import android.widget.*;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends Activity
{

    //The layout that holds the piano keys.
    LinearLayout pianoKeysContainer;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        pianoKeysContainer = (LinearLayout) findViewById(R.id.key_container);
        pianoKeysContainer.setOnTouchListener(onYourViewTouchListener);
    }


    //Here we load the view positions after render it and fill the array with the positions
    private List<Integer> positionsLeft_whiteKeys  = new ArrayList<Integer>();
    private List<Integer> positionsRight_whiteKeys = new ArrayList<Integer>();

    public void onWindowFocusChanged(boolean hasFocus)
    {
        super.onWindowFocusChanged(hasFocus);

        for (int i = 0; i < pianoKeysContainer.getChildCount(); i++)
        {
            //positionsLeft_whiteKeys holds the start x of each view.
            positionsLeft_whiteKeys.add(pianoKeysContainer.getChildAt(i).getLeft());
            //positionsRight_whiteKeys holds the end x of each view.
            positionsRight_whiteKeys.add(pianoKeysContainer.getChildAt(i).getRight());
        }
    }

    public View.OnTouchListener onYourViewTouchListener = new View.OnTouchListener()
    {
        float positionX;
        FrameLayout pianoKey;
        FrameLayout lastPlayedKey;
        ArrayList<FrameLayout> pressedKeys = new ArrayList<FrameLayout>();

        @Override
        public boolean onTouch(View view, MotionEvent motionEvent)
        {

            positionX = motionEvent.getX();

            float pitch;

            //Looping on the child of the layout which contains the piano keys
            for (int x = 0; x < ((LinearLayout) view).getChildCount(); x++)
            {
                // Calculating the pitch to get good chords
                pitch = (float) Math.pow(Math.pow(2.0, 1 / 12.0), (float) x);

                pianoKey = (FrameLayout) ((LinearLayout) view).getChildAt(x);

                if (positionsLeft_whiteKeys.size() >= 0 && positionsRight_whiteKeys.size() >= 0)
                {
                    if (positionX > positionsLeft_whiteKeys.get(x) && positionX < positionsRight_whiteKeys.get(x))
                    {
                        pianoKey = (FrameLayout) ((LinearLayout) view).getChildAt(x);

                        if (pianoKey != null)
                        {
                            pianoKey.setBackgroundResource(R.drawable.piano_key_pressed);
                            pressedKeys.add(pianoKey);
                        }
                        if (lastPlayedKey != pianoKey)
                            playKey(pitch);

                        lastPlayedKey = pianoKey;
                        break;
                    }

                    if (lastPlayedKey != null)
                    {
                        pianoKey.setBackgroundResource(R.drawable.piano_key);
                        lastPlayedKey.setBackgroundResource(R.drawable.piano_key);

                    }
                }
            }

            if (motionEvent.getAction() == MotionEvent.ACTION_UP)
            {
                lastPlayedKey = null;

                for (FrameLayout pressedKey : pressedKeys)
                {
                    pressedKey.setBackgroundResource(R.drawable.piano_key);
                }


            }

            return false;
        }
    };


    //This is sound play method
    SoundPool   sp = new SoundPool(1, AudioManager.STREAM_MUSIC, 1);
    public void playKey(final float pitch)
    {

        //here you should store your piano sound at res/raw then load it
        sp.load(this, R.raw.piano, 1);

        sp.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener()
        {
            @Override
            public void onLoadComplete(SoundPool soundPool, int i, int i2)
            {
                soundPool.play(i, 0.99f, 0.99f, 1, 0, pitch);
            }
        });
    }

}

And this is the xml file (main.xml) 这是xml文件(main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        android:id="@+id/key_container">

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_marginRight="2dp"
            android:layout_width="48dp"
            android:background="@drawable/piano_key"/>

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_marginRight="2dp"
            android:layout_width="48dp"
            android:background="@drawable/piano_key"/>

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_marginRight="2dp"
            android:layout_width="48dp"
            android:background="@drawable/piano_key"/>

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_marginRight="2dp"
            android:layout_width="48dp"
            android:background="@drawable/piano_key"/>

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_marginRight="2dp"
            android:layout_width="48dp"
            android:background="@drawable/piano_key"
            />

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_marginRight="2dp"
            android:layout_width="48dp"
            android:background="@drawable/piano_key"/>

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_marginRight="2dp"
            android:layout_width="48dp"
            android:background="@drawable/piano_key"/>

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_marginRight="2dp"
            android:layout_width="48dp"
            android:background="@drawable/piano_key"/>

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_marginRight="2dp"
            android:layout_width="48dp"
            android:background="@drawable/piano_key"/>

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_marginRight="2dp"
            android:layout_width="48dp"
            android:background="@drawable/piano_key"/>

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_marginRight="2dp"
            android:layout_width="48dp"
            android:background="@drawable/piano_key"/>

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_marginRight="2dp"
            android:layout_width="48dp"
            android:background="@drawable/piano_key"/>

    </LinearLayout>


</LinearLayout>

Note: the only thing you should do to complete the example is to put you piano key image (pressed and not pressed) and put the piano sound at res/raw 注意:要完成该示例,您唯一要做的就是将钢琴琴键图像(按和不按)放置在RES / RAW上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM