키 버튼의 추가
안드로이드 그래픽에 대한 간단한 공부가 끝났으므로 본격적으로 레이아웃을 잡아보기로 했다.
원래 생각했던 그림대로 상단에 ImageView를 두고 하단에는 수많은 버튼들을 배치하기 위해 LinearLayout 층을 겹겹히 쌓아보았다.

에뮬레이터 화면에는 아래와 같이 출력이 됐다.

일단 지판 그림이 너무 작아서 사이즈 조정을 해보기로 했다.

디자인이 그닥 감동적이진 않지만, 기능을 구현하는 프레임으로서는 나쁘지 않다고 믿어보면서 계속 진행하기로 했다.
Java에는 #define이 없다고 해서 private final static으로 처리했다.
그래픽에서 이렇게 절대 좌표를 줘도 되는 것인지는 아직 잘 모르겠다.
public class MainActivity extends AppCompatActivity {
private final static int IMAGE_START_X = 20;
private final static int IMAGE_START_Y = 100;
private final static int FRET_START_X = IMAGE_START_X+20;
private final static int FRET_DISTANCE_X = 120;
private final static int LINE_DISTANCE_Y = 55;
private void drawFretMark(int x, int y, Path path)
{
path.reset();
path.moveTo(x, y-30); // first point
path.lineTo(x, y); // second point
path.lineTo(x+15, y); // third point
path.lineTo(x, y-30); // return to the first point
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Paint paint = new Paint();
paint.setColor(Color.parseColor(("#101010")));
paint.setStrokeWidth(4);
Bitmap bg = Bitmap.createBitmap(1400,460, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bg);
// draw horizontal lines
for(int i=0;i<6;i++){
canvas.drawLine(IMAGE_START_X,IMAGE_START_Y+LINE_DISTANCE_Y*i,1400,IMAGE_START_Y+LINE_DISTANCE_Y*i, paint);
}
// draw rectangle on the Fret0 side
canvas.drawRect(IMAGE_START_X,IMAGE_START_Y,FRET_START_X,IMAGE_START_Y+LINE_DISTANCE_Y*5, paint);
// draw vertical lines
for(int i=1;i<12;i++){
canvas.drawLine(FRET_START_X+FRET_DISTANCE_X*i,IMAGE_START_Y,FRET_START_X+FRET_DISTANCE_X*i,IMAGE_START_Y+LINE_DISTANCE_Y*5, paint);
}
canvas.drawLine(FRET_START_X+FRET_DISTANCE_X*11+6,IMAGE_START_Y,FRET_START_X+FRET_DISTANCE_X*11+6,IMAGE_START_Y+LINE_DISTANCE_Y*5, paint);
// draw triangle Fret mark
Path path = new Path();
paint.setColor(Color.parseColor(("#505050")));
for(int i=0;i<5;i++) {
drawFretMark(FRET_START_X+i*(FRET_DISTANCE_X*2), IMAGE_START_Y+LINE_DISTANCE_Y*5, path);
canvas.drawPath(path, paint);
}
drawFretMark(FRET_START_X+FRET_DISTANCE_X*11+6, IMAGE_START_Y+LINE_DISTANCE_Y*5, path);
canvas.drawPath(path, paint);
canvas.drawCircle(FRET_START_X+FRET_DISTANCE_X/2, IMAGE_START_Y, 14, paint);
ImageView iv = findViewById(R.id.image);
iv.setImageBitmap(bg);
}
}
[키 버튼 추가 하기]

3 열에 Key 버튼을 추가하는데 약간의 문제가 있었다.
아랫쪽 버튼들은 minHeight와 minWidth가 지정된 기본 형태인데,
3 열에 많은 수의 버튼을 넣다보니 오른쪽과 아랫쪽으로 밀리는 문제가 생겼다.
버튼의 사이즈를 줄이는 방법을 알아보니 각각의 버튼에 모두 minHeight와 minWidth를 0으로 지정하라고 한다,
<Button
android:id="@+id/button_c"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:minHeight="0dp"
android:minWidth="0dp"
android:text="C" />
C,D,E,F,G,A,B와 #, b(플랫 기호가 없어서 일단 b로 함) 버튼을 모두 위와 같이 지정했다.
#,b는 layout_weight를 1로 주고 C,..,B 버튼에는 2를 줘서 버튼의 가로 넓이에 차이를 줬다.
B와 # 사이의 간격은 B 버튼에 maginRight를 준 것이다.
<Button
android:id="@+id/button_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="100dp"
android:layout_weight="2"
android:minHeight="0dp"
android:minWidth="0dp"
android:text="B" />
이제 각 키 버튼을 누를 때마다, 지판에 해당 스케일이 표시되도록 할 차례이다.
일단 여기에서 한가지 정리가 필요할 것 같다.
Android 그래픽을 배우면서 테스트하는 중이라,
지금까지 OnCreate()에 주저리주저리 그리는 코드를 작성했었다.
그런데 앞으로는 생성시 뿐만이 아니라,
버튼을 누를 때마다 그림을 그려야 할 것 같으므로 프렛을 그리는 코드를 함수로 따로 빼놓는게 맞는 것 같다.
그래서 일차적으로 아래와 같이 이미지 그리는 코드를 drawFret이라는 함수를 만들고 몰아 넣어보았다.
private void drawFret(Paint paint, Canvas canvas, Bitmap bg)
{
paint.setColor(Color.parseColor(("#101010")));
paint.setStrokeWidth(4);
for(int i = 0;i<6;i++)
{
// draw horizontal lines
canvas.drawLine(IMAGE_START_X, IMAGE_START_Y + LINE_DISTANCE_Y * i, 1400, IMAGE_START_Y + LINE_DISTANCE_Y * i, paint);
}
// draw rectangle on the Fret0 side
...
ImageView iv = findViewById(R.id.image);
iv.setImageBitmap(bg);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Paint paint = new Paint();
Bitmap bg = Bitmap.createBitmap(1400,460, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bg);
drawFret(paint, canvas, bg);
Button buttonC = (Button) findViewById(R.id.button_c) ;
buttonC.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View view) {
}
}) ;
이제 drawFret에서 각 프렛에 동그라미와 함께 note를 표시할 차례가 되었다.
동그라미 그리는 것은 간단히 해결되었다.
paint.setColor(Color.parseColor(("#C0C0C0")));
for(int i=0;i<12;i++)
for(int j=0;j<6;j++)
{
canvas.drawCircle(FRET_START_X+FRET_DISTANCE_X * i+ FRET_DISTANCE_X/2,
IMAGE_START_Y+LINE_DISTANCE_Y*j,22,paint);
}

다음으로는 각 동그라미 안에 note를 표시해야 하는데, 이건 생각이 좀 필요할 듯하다.