Android实现简易版弹钢琴效果

本文实例为大家分享了Android实现弹钢琴效果展示的具体代码,供大家参考,具体内容如下

目标效果:

1.drawable下新建button_selector.xml页面:

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@drawable/button_pressed" android:state_pressed="true"></item>

<item android:drawable="@drawable/button"></item>

</selector>

2.drawable下新建button.xml页面:

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android" >

<corners

android:bottomLeftRadius="10dp"

android:bottomRightRadius="10dp" >

</corners>

<stroke

android:width="2dp"

android:color="#605C59" />

<gradient

android:angle="270"

android:endColor="#FFFFFF"

android:startColor="#F5F5F5" />

</shape>

3.drawable下新建button_pressed.xml页面:

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android" >

<solid android:color="#A4A4A4" />

<corners

android:bottomLeftRadius="10dp"

android:bottomRightRadius="10dp" >

</corners>

<stroke

android:width="2dp"

android:color="#605C59" />

</shape>

4.新建PanioMusic.java类

package com.example.weixu.view;

/**

* 音乐播放帮助类

*/

import java.util.HashMap;

import android.content.Context;

import android.media.AudioManager;

import android.media.SoundPool;

import com.example.weixu.playpanio.R;

public class PanioMusic {

// 资源文件

int Music[] = {R.raw.do1, R.raw.re2, R.raw.mi3, R.raw.fa4, R.raw.sol5,

R.raw.la6, R.raw.si7,};

SoundPool soundPool;

HashMap<Integer, Integer> soundPoolMap;

public PanioMusic(Context context) {

soundPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 100);

soundPoolMap = new HashMap<Integer, Integer>();

for (int i = 0; i < Music.length; i++) {

soundPoolMap.put(i, soundPool.load(context, Music[i], 1));

}

}

public int soundPlay(int no) {

return soundPool.play(soundPoolMap.get(no), 100, 100, 1, 0, 1.0f);

}

public int soundOver() {

return soundPool.play(soundPoolMap.get(1), 100, 100, 1, 0, 1.0f);

}

@Override

protected void finalize() throws Throwable {

soundPool.release();

super.finalize();

}

}

5.activity_main.xml页面:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/llparent"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context=".MainActivity" >

<LinearLayout

android:id="@+id/llKeys"

android:layout_width="match_parent"

android:layout_height="0dp"

android:layout_weight="5"

android:orientation="horizontal"

android:padding="10dp" >

<Button

android:id="@+id/btPanioOne"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="1" />

<Button

android:id="@+id/btPanioTwo"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="2" />

<Button

android:id="@+id/btPanioThree"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="3" />

<Button

android:id="@+id/btPanioFour"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="4" />

<Button

android:id="@+id/btPanioFive"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="5" />

<Button

android:id="@+id/btPanioSix"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="6" />

<Button

android:id="@+id/btPanioSeven"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="7" />

</LinearLayout>

</LinearLayout>

6.MainActivity.java页面:

package com.example.weixu.playpanio;

import android.os.Bundle;

import android.app.Activity;

import android.util.Log;

import android.view.MotionEvent;

import android.view.View;

import android.view.View.OnTouchListener;

import android.widget.Button;

import com.example.weixu.view.PanioMusic;

public class MainActivity extends Activity {

private Button button[];// 按钮数组

private PanioMusic utils;// 工具类

private View parent;// 父视图

private int buttonId[];// 按钮id

private boolean havePlayed[];// 是否已经播放了声音,当手指在同一个按钮内滑动,且已经发声,就为true

private View keys;// 按钮们所在的视图

private int pressedkey[];

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

init();

parent = (View) findViewById(R.id.llparent);

parent.setClickable(true);

parent.setOnTouchListener(new OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

int temp;

int tempIndex;

int pointercount;

pointercount = event.getPointerCount();

for (int count = 0; count < pointercount; count++) {

boolean moveflag = false;// 标记是否是在按键上移动

temp = isInAnyScale(event.getX(count), event.getY(count),

button);

if (temp != -1) {// 事件对应的是当前点

switch (event.getActionMasked()) {

case MotionEvent.ACTION_DOWN:

// // 单独一根手指或最先按下的那个

// pressedkey = temp;

case MotionEvent.ACTION_POINTER_DOWN:

Log.i("--", "count" + count);

pressedkey[count] = temp;

if (!havePlayed[temp]) {// 在某个按键范围内

button[temp]

.setBackgroundResource(R.drawable.button_pressed);

// 播放音阶

utils.soundPlay(temp);

Log.i("--", "sound" + temp);

havePlayed[temp] = true;

}

break;

case MotionEvent.ACTION_MOVE:

temp = pressedkey[count];

for (int i = temp + 1; i >= temp - 1; i--) {

// 当在两端的按钮时,会有一边越界

if (i < 0 || i >= button.length) {

continue;

}

if (isInScale(event.getX(count),

event.getY(count), button[i])) {// 在某个按键内

moveflag = true;

if (i != temp) {// 在相邻按键内

boolean laststill = false;

boolean nextstill = false;

// 假设手指已经从上一个位置抬起,但是没有真的抬起,所以不移位

pressedkey[count] = -1;

for (int j = 0; j < pointercount; j++) {

if (pressedkey[j] == temp) {

laststill = true;

}

if (pressedkey[j] == i) {

nextstill = true;

}

}

if (!nextstill) {// 移入的按键没有按下

// 设置当前按键

button[i]

.setBackgroundResource(R.drawable.button_pressed);

// 发音

utils.soundPlay(i);

havePlayed[i] = true;

}

pressedkey[count] = i;

if (!laststill) {// 没有手指按在上面

// 设置上一个按键

button[temp]

.setBackgroundResource(R.drawable.button);

havePlayed[temp] = false;

}

break;

}

}

}

break;

case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_POINTER_UP:

// 事件与点对应

tempIndex = event.getActionIndex();

if (tempIndex == count) {

Log.i("--", "index" + tempIndex);

boolean still = false;

// 当前点已抬起

for (int t = count; t < 5; t++) {

if (t != 4) {

if (pressedkey[t + 1] >= 0) {

pressedkey[t] = pressedkey[t + 1];

} else {

pressedkey[t] = -1;

}

} else {

pressedkey[t] = -1;

}

}

for (int i = 0; i < pressedkey.length; i++) {// 是否还有其他点

if (pressedkey[i] == temp) {

still = true;

break;

}

}

if (!still) {// 已经没有手指按在该键上

button[temp]

.setBackgroundResource(R.drawable.button);

havePlayed[temp] = false;

Log.i("--", "button" + temp + "up");

}

break;

}

}

}

//

if (event.getActionMasked() == MotionEvent.ACTION_MOVE

&& !moveflag) {

if (pressedkey[count] != -1) {

button[pressedkey[count]]

.setBackgroundResource(R.drawable.button);

havePlayed[pressedkey[count]] = false;

}

}

}

return false;

}

});

keys = (View) findViewById(R.id.llKeys);

}

private void init() {

// 新建工具类

utils = new PanioMusic(getApplicationContext());

// 按钮资源Id

buttonId = new int[7];

buttonId[0] = R.id.btPanioOne;

buttonId[1] = R.id.btPanioTwo;

buttonId[2] = R.id.btPanioThree;

buttonId[3] = R.id.btPanioFour;

buttonId[4] = R.id.btPanioFive;

buttonId[5] = R.id.btPanioSix;

buttonId[6] = R.id.btPanioSeven;

button = new Button[7];

havePlayed = new boolean[7];

// 获取按钮对象

for (int i = 0; i < button.length; i++) {

button[i] = (Button) findViewById(buttonId[i]);

button[i].setClickable(false);

havePlayed[i] = false;

}

pressedkey = new int[5];

for (int j = 0; j < pressedkey.length; j++) {

pressedkey[j] = -1;

}

}

/**

* 判断某个点是否在某个按钮的范围内

*

* @param x 横坐标

* @param y 纵坐标

* @param button 按钮对象

* @return 在:true;不在:false

*/

private boolean isInScale(float x, float y, Button button) {

// keys.getTop()是获取按钮所在父视图相对其父视图的右上角纵坐标

if (x > button.getLeft() && x < button.getRight()

&& y > button.getTop() + keys.getTop()

&& y < button.getBottom() + keys.getTop()) {

return true;

} else {

return false;

}

}

/**

* 判断某个点是否在一个按钮集合中的某个按钮内

*

* @param x 横坐标

* @param y 纵坐标

* @param button 按钮数组

* @return

*/

private int isInAnyScale(float x, float y, Button[] button) {

// keys.getTop()是获取按钮所在父视图相对其父视图的右上角纵坐标

for (int i = 0; i < button.length; i++) {

if (x > button[i].getLeft() && x < button[i].getRight()

&& y > button[i].getTop() + keys.getTop()

&& y < button[i].getBottom() + keys.getTop()) {

return i;

}

}

return -1;

}

}

7.AndroidManifest.xml页面对某个Activity页面进行设置横屏

android:screenOrientation="landscape"

8.另外,每个按键的音效需要提前导入res下raw文件夹中。

源码:点击打开链接

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 Android实现简易版弹钢琴效果 的全部内容, 来源链接: utcz.com/p/241873.html

回到顶部