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

目标效果:

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

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

android:bottomLeftRadius="10dp"

android:bottomRightRadius="10dp" >

android:width="2dp"

android:color="#605C59" />

android:angle="270"

android:endColor="#FFFFFF"

android:startColor="#F5F5F5" />

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

android:bottomLeftRadius="10dp"

android:bottomRightRadius="10dp" >

android:width="2dp"

android:color="#605C59" />

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 soundPoolMap;

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页面:

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" >

android:id="@+id/llKeys"

android:layout_width="match_parent"

android:layout_height="0dp"

android:layout_weight="5"

android:orientation="horizontal"

android:padding="10dp" >

android:id="@+id/btPanioOne"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="1" />

android:id="@+id/btPanioTwo"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="2" />

android:id="@+id/btPanioThree"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="3" />

android:id="@+id/btPanioFour"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="4" />

android:id="@+id/btPanioFive"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="5" />

android:id="@+id/btPanioSix"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="6" />

android:id="@+id/btPanioSeven"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/button"

android:text="7" />

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钢琴滑动代码,Android实现简易版弹钢琴效果相关推荐

  1. Android钢琴滑动代码,android 钢琴界面实现

    近在做一个钢琴的东西,关于这个界面如何设计画了很长时间,主要是考虑到针对不同的分辨率,如果只针对一种分辨率的话用绝对布局可以实现,实现的基本思想是每个白色的键的位置是可以计算出来的,屏幕的宽度可以获得 ...

  2. Android钢琴滑动代码,真正完美的android钢琴软件

    8年前 (2013-03-18) | 33,859 views | 35 条评论 | 本文共949个字 现在手机钢琴软件已经相当多了,命名也是一个比一个牛,不过要想满足我的需求,那可真的是比登天还难, ...

  3. android小球移动代码,Android自定义圆形View实现小球跟随手指移动效果

    本文实例为大家分享了Android实现小球跟随手指移动效果的具体代码,供大家参考,具体内容如下 一. 需求功能 手指在屏幕上滑动,红色的小球始终跟随手指移动. 实现的思路: 1)自定义View,在on ...

  4. android gridview滑动卡,Android RecyclerView的卡顿问题

    本文其实是上一篇Android本地app操作相关基础的延伸,然而内容基本没什么联系了(初学者身份瞬间暴露,打一枪换一个地方←_←),就不好意思再添个"续"或者"(2)&q ...

  5. Android可滑动画板,Android 利用 Canvas 画画板

    首先新建一个项目工程,建立文件,如下图所示 首先配置页面布局文件activity_main.xml,如下图所示: xmlns:tools="http://schemas.android.co ...

  6. android手势滑动页面,Android 手势识别 (左右滑动)实现 页面 切换

    要实现 页面左右滑动的效果  就一定要由手势识别器, 就是这个对象 GestureDetector. 用法其实很简单,这里 写一下 方便以后用到的时候好找. 步骤就是 这样子 123.. 1. 初始化 ...

  7. android 横向滑动 回弹,android ScrollView水平滑动回弹

    在研究了View的一些属性之后做了个Scroll的水平滑动回弹. 效果图: 主要代码: import android.content.Context; import android.graphics. ...

  8. android调频收音机代码,android 收音机 FM 驱动 hal层 框架层以及应用层代码

    [实例简介] android 收音机 FM 驱动 hal层 框架层以及应用层代码 方法一 不需要framework部分 1.fm放到 \hardware\rk2x 2.FmRadio 放到 packa ...

  9. android确认密码代码,Android自定义View实现验证码or密码输入框

    前言 最近项目中有支付功能,用户输入密码时要类似微信支付密码输入框的样式,本想直接copy网上的,但设计姐姐总是对样式挑三拣四,抽空自己自定义了一个,无奈之下抽空自定义了个,并把它贴到GitHub上供 ...

最新文章

  1. Win7 任务栏影藏、显示速度提升
  2. React UI 库:React Suite 3.7.8 版本更新
  3. linux线程下的读写锁
  4. 目标检测 nms非极大抑制算法
  5. 在ubuntn kylin系统eclipse中Java语言helloworld程序
  6. 将markdown编译为HTML和PDF
  7. Java SSM6——SSM整合
  8. c++ signal 信号退出
  9. 【白皮书分享】人工智能“新基建”发展白皮书.pdf(附下载链接)
  10. delphi listview动态添加图片_Java 添加PDF图章(印章)——图片图章、动态图章
  11. php转到qq并分享,php怎么实现qq分享
  12. 使用OD修改程序窗口标题和提示信息
  13. Java 员工信息管理系统
  14. 开发微信“自动抢红包”软件,被罚400多万
  15. 万字长文 | 谷歌进入到退出中国市场的前因后果
  16. 如何在一台手机上,同时登录两个微信号?
  17. 摩拜与ofo, 你们这是为了共享单车还是共享经济?
  18. 【RL系列】马尔可夫决策过程——Gambler's Problem
  19. 华为云管理网络2.0,志不止于网络
  20. 运动世界校园破解刷跑步数据

热门文章

  1. netlify 部署 github page, 使用https域名
  2. python 进阶 【封装】 适合小白入门
  3. Codevs 1228 苹果树
  4. url action editor 快速修改swf链接
  5. 渗透测试——sql注入进阶/基于时间的盲注/一看就会/
  6. Mysql可视化软件-Navicat和SQLyog
  7. Python logging log日志写入文件
  8. MySQL各种引擎特点简述
  9. 拼音翻译成阿拉伯数字
  10. ie浏览器下载地址(官网地址)