Android实现简易版弹钢琴效果

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

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

Android实现简易版弹钢琴效果_第1张图片

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

  • 整个钢琴实现的效果图

Android实现简易版弹钢琴效果_第2张图片

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

Android实现简易版弹钢琴效果_第3张图片

Android实现简易版弹钢琴效果_第4张图片

  • 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 Studio 增加按钮响应事件
  4. Android - 按钮组件详解
  5. Android点击左右按钮实现左右滑动页面切换
  6. googleMap----放大,缩小,东南西北,四种视图切换代码

随机推荐

  1. Android(安卓)Dialog 使用 ConstraintLay
  2. android自定义Toast视图
  3. Android控件指定方向加边框
  4. Android(安卓)- 永不锁屏,开机不锁屏,删除
  5. vuforia android 教程(1) 利用vuforia an
  6. C#服务端+C#客户端+android客户端,socket
  7. Android的GridView控件点击图片变暗效果
  8. Using color in Android, by XML
  9. Android获取声音长度
  10. classList对象、blur事件进行表单非空验