Skip to content

Instantly share code, notes, and snippets.

@ssaurel
Created March 20, 2018 10:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssaurel/7a553ded46a9860e950beadb68bc89ba to your computer and use it in GitHub Desktop.
Save ssaurel/7a553ded46a9860e950beadb68bc89ba to your computer and use it in GitHub Desktop.
PianoView for a tutorial on the SSaurel's Channel
package com.ssaurel.piano;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
/**
* Created by ssaurel on 15/03/2018.
*/
public class PianoView extends View {
public static final int NB = 14;
private Paint black, yellow, white;
private ArrayList<Key> whites = new ArrayList<>();
private ArrayList<Key> blacks = new ArrayList<>();
private int keyWidth, height;
private AudioSoundPlayer soundPlayer;
public PianoView(Context context, AttributeSet attrs) {
super(context, attrs);
black = new Paint();
black.setColor(Color.BLACK);
white = new Paint();
white.setColor(Color.WHITE);
white.setStyle(Paint.Style.FILL);
yellow = new Paint();
yellow.setColor(Color.YELLOW);
yellow.setStyle(Paint.Style.FILL);
soundPlayer = new AudioSoundPlayer(context);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
keyWidth = w / NB;
height = h;
int count = 15;
for (int i = 0; i < NB; i++) {
int left = i * keyWidth;
int right = left + keyWidth;
if (i == NB - 1) {
right = w;
}
RectF rect = new RectF(left, 0, right, h);
whites.add(new Key(rect, i + 1));
if (i != 0 && i != 3 && i != 7 && i != 10) {
rect = new RectF((float) (i - 1) * keyWidth + 0.5f * keyWidth + 0.25f * keyWidth, 0,
(float) i * keyWidth + 0.25f * keyWidth, 0.67f * height);
blacks.add(new Key(rect, count));
count++;
}
}
}
@Override
protected void onDraw(Canvas canvas) {
for (Key k : whites) {
canvas.drawRect(k.rect, k.down ? yellow : white);
}
for (int i = 1; i < NB; i++) {
canvas.drawLine(i * keyWidth, 0, i * keyWidth, height, black);
}
for (Key k : blacks) {
canvas.drawRect(k.rect, k.down ? yellow : black);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
boolean isDownAction = action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE;
for (int touchIndex = 0; touchIndex < event.getPointerCount(); touchIndex++) {
float x = event.getX(touchIndex);
float y = event.getY(touchIndex);
Key k = keyForCoords(x,y);
if (k != null) {
k.down = isDownAction;
}
}
ArrayList<Key> tmp = new ArrayList<>(whites);
tmp.addAll(blacks);
for (Key k : tmp) {
if (k.down) {
if (!soundPlayer.isNotePlaying(k.sound)) {
soundPlayer.playNote(k.sound);
invalidate();
} else {
releaseKey(k);
}
} else {
soundPlayer.stopNote(k.sound);
releaseKey(k);
}
}
return true;
}
private Key keyForCoords(float x, float y) {
for (Key k : blacks) {
if (k.rect.contains(x,y)) {
return k;
}
}
for (Key k : whites) {
if (k.rect.contains(x,y)) {
return k;
}
}
return null;
}
private void releaseKey(final Key k) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
k.down = false;
handler.sendEmptyMessage(0);
}
}, 100);
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
invalidate();
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment