Android实现简易版弹钢琴效果

参考于:https://www.jb51.net/article/161904.htm

最近由于要写Android的期末报告,老师让写一个类似于钢琴的小程序,但对深受网课熏陶的我来说,嗯!!!这是个大问题,一学期快结束了,课没怎么听,回放还没有???这作业怎么写???于是,百度出现了,百度是真的香!!!虽然,他广告多,还收费,链接假……但他实用!!!嗯,不会写作业 ???问度娘就好了。于是参考了上面链接的东西。说实话,第一遍看,没怎么看懂!!确实,毕竟没听课嘛,也不为过,都是这考试的错,毕竟量劫来袭,贫道闭关静颂黄庭!不怨我!毕竟家里网不好,住在山沟沟里……反正各种理由就是不想上网课。但是要写作业,毕竟不想挂科!!!

好了,终止废话。干货如下:

  • 整个钢琴实现的效果图

  • 整个APP的整体框架!!!!!这里很重要!!!!

  • 1.新建activity_main.xml文件源码
<RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/parents"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:background="@drawable/background">    <LinearLayout        android:id="@+id/llKeys"        android:layout_width="wrap_content"        android:layout_height="match_parent"        android:layout_weight="5"        android:layout_alignParentBottom="true"        android:orientation="horizontal"        android:padding="10dp" >        <Button            android:id="@+id/iv_do"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/icon_do" />        <Button            android:id="@+id/iv_re"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/icon_re" />        <Button            android:id="@+id/iv_mi"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/icon_mi"/>        <Button            android:id="@+id/iv_fa"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/icon_fa"/>        <Button            android:id="@+id/iv_so"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/icon_so"/>        <Button            android:id="@+id/iv_la"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/icon_la" />        <Button            android:id="@+id/iv_si"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@drawable/icon_si"/>    </LinearLayout></RelativeLayout>
  • 2.新建PanioMusic.java文件
/** * 音乐播放工具类 */import java.util.HashMap;import android.content.Context;import android.media.AudioManager;import android.media.SoundPool;import com.example.pinao.R;public class Pinao {    // 资源文件    int Music[] = {R.raw.dol, 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 Pinao(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();    }}
  • 3.新建MainActivity.java文件
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.pinao.Pinao;public class MainActivity extends Activity {    private Button button[];// 按钮数组    private Pinao 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.parents);        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]) {// 在某个按键范围内                                    // 播放音阶                                    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) {// 移入的按键没有按下                                                // 发音                                                utils.soundPlay(i);                                                havePlayed[i] = true;                                            }                                            pressedkey[count] = i;                                            if (!laststill) {// 没有手指按在上面                                                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) {// 已经没有手指按在该键上                                        havePlayed[temp] = false;                                        Log.i("--", "button" + temp + "up");                                    }                                    break;                                }                        }                    }                    //                    if (event.getActionMasked() == MotionEvent.ACTION_MOVE                            && !moveflag) {                        if (pressedkey[count] != -1) {                            havePlayed[pressedkey[count]] = false;                        }                    }                }                return false;            }        });        keys = (View) findViewById(R.id.llKeys);    }    private void init() {        // 新建工具类        utils = new Pinao(getApplicationContext());        // 按钮资源Id        buttonId = new int[7];        buttonId[0] = R.id.iv_do;        buttonId[1] = R.id.iv_re;        buttonId[2] = R.id.iv_mi;        buttonId[3] = R.id.iv_fa;        buttonId[4] = R.id.iv_so;        buttonId[5] = R.id.iv_la;        buttonId[6] = R.id.iv_si;        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;    }}

以上就是全部源码文件!!!

  • 至于相关的音频素材可自行百度获取。

  • 源码文件素材地址:https://download.csdn.net/download/m0_46153949/12536768

更多相关文章

  1. [Android]ListView性能优化之视图缓存
  2. [Android]直接使用代码建立Android视图元件
  3. Android开发实例详解之IMF(Android(安卓)SDK Sample—SoftKeyboar
  4. Android入门教程(五)之------第一个Android工程HelloAndroid
  5. Android入门教程(五)之------第一个Android工程HelloAndroid
  6. Android(安卓)开发者 for Flutter (1)Flutter和Android中的View对
  7. Android中 android:layout_weight 属性
  8. Android(安卓)SDK 2.3与Eclipse最新版开发环境搭建(三)
  9. Android的介绍

随机推荐

  1. Android应用程序架构
  2. Android(安卓)RTC 自下而上分析
  3. Android(安卓)重点知识回顾
  4. android studio 更改快捷键为eclipse中习
  5. Android(安卓)Widgets
  6. 基于ffmpeg的Android播放器开源代码
  7. Android(安卓)如何在屏幕切换的时候页面
  8. Android平台安全分析
  9. AsynTask 异步任务
  10. Android(安卓)15本经典教程和150多个实例