十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
这篇文章给大家分享的是有关Android如何实现简易版弹钢琴效果的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
创新互联长期为1000+客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为冀州企业提供专业的成都网站制作、成都网站设计、外贸营销网站建设,冀州网站改版等技术服务。拥有10多年丰富建站经验和众多成功案例,为您定制开发。
具体内容如下
目标效果:
1.drawable下新建button_selector.xml页面:
2.drawable下新建button.xml页面:
3.drawable下新建button_pressed.xml页面:
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; HashMapsoundPoolMap; public PanioMusic(Context context) { soundPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 100); soundPoolMap = new HashMap (); 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页面:
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如何实现简易版弹钢琴效果”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!