1

所以我想为android制作一个简单的触摸屏吉他指法创建器,但我真的不知道该使用什么方法。我对编写应用程序相当陌生,但我对 java 很满意。吉他指板看起来像这样。http://upload.wikimedia.org/wikipedia/commons/3/37/Guitar_Fretboard_Open_Strings_Diagram.png

1)起初我倾向于为每个琴弦和音品制作按钮,但我认为这可能有点困难,因为吉他上有 24 个音品和 6 个琴弦(144 个按钮),每次按下按钮都会更新和具有 6 行和 x 列的数组。我会将按钮放置在图像上的品格处并使其不可见,但是将按钮排成一行可能会很棘手,并且它们可能无法按我想要的方式缩放。

一个数组可以很方便地保存这些值,因为指法谱是这样写的......

e string -------
b string ----2--
g string ------3
d string 0-0----
a string -------
E string ------- 

品格编号被写入。

我什至不确定从哪里开始使用这种方法。我应该为每个按钮设置一个单独的方法,因为它们都有不同的值吗?要从按钮到数组中获取值,我需要放置类似的东西

strArray[计数,n]

其中 count 是方法之外的变量,n 是单击按钮时返回的变量。计数将使用下一个/上一个按钮增加或减少,以便它可以遍历数组

2)我在看这个方法http://blahti.wordpress.com/2012/06/26/images-with-clickable-areas/看起来它可以工作,但开发人员使用颜色来告诉不同的热门现货,我认为这可能是不可行的,因为我需要 144 种不同的颜色。

有没有更简单的方法可以实现这个?

抱歉,如果我没有很好地解释,我是在 android 上开发的新手,我有很多问题。

4

1 回答 1

1

在较大背景的顶部使用不可见的按钮在概念上很容易,但会出现您提到的可伸缩性问题。它也不能很好地识别多个同时触摸。第二种方法的核心,使用触摸,可能是你想走的路。onTouch() 方法中的 MotionEvent 将为您提供触摸的位置和动作。然后它就变成了一个练习,用适当的音柱或琴弦来翻译触摸/移动/抬起的点的坐标。

有很多关于触摸识别的不错的教程。这是一个

编辑:

有几种方法可以在触摸位置和所需的琴弦和音品之间进行转换。一种方法是只对每个触摸事件strng = x / (width / NUM_STRINGS)进行计算fret = y / (height / NUM_FRETS)。(假设字符串在显示屏上纵向绘制。)

另一种直接的方法是构建和使用查找表来进行翻译。这确实需要几千字节来存储整数,但允许进行几个快速数组查找来确定字符串和音品。

这是实现后一种方法的示例活动。它包含一些假设和捷径,但基本功能应该是相当健全的。只有down事件显示翻译;您还需要为 up 和 move 事件做一些适当的事情。

MainActivity.java

package com.example.guitar;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends Activity
                          implements OnTouchListener, ViewTreeObserver.OnGlobalLayoutListener {

    final static String TAG = "MainActivity";
    final static int NUM_STRINGS = 6;
    final static int NUM_FRETS = 12;

    ImageView img = null;
    LinearLayout layout = null;

    int width = 0;
    int height = 0;

    int touchToString[] = null;
    int touchToFret[] = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        layout = (LinearLayout) findViewById(R.id.layout);
        layout.setOnTouchListener(this);
        layout.getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    public boolean onTouch(View v, MotionEvent event) {
        // Handle the touch event:
        int idx = event.getActionIndex();
        int id = event.getPointerId(idx);
        int x = (int) event.getX(idx);
        int y = (int) event.getY(idx);         

        switch (event.getActionMasked()) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_POINTER_DOWN:            
            Log.d(TAG, String.format("DOWN event for pointer %d at %d, %d", id, x, y));

            // If touch is within the bounds of the layout:
            if (x > 0 && x < width && y > 0 && y < height)                
                Log.i(TAG, String.format("Pressed string %d at fret position %d",
                                         touchToString[x], touchToFret[y]));
            break;

        case MotionEvent.ACTION_MOVE:
            for (int ptr = 0; ptr < event.getPointerCount(); ptr++)
                Log.d(TAG, String.format("MOVE event for pointer %d at %d, %d",
                      event.getPointerId(ptr), (int) event.getX(ptr), (int) event.getY(ptr)));
            break;

        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
        case MotionEvent.ACTION_CANCEL:
            Log.d(TAG, String.format("UP event for pointer %d at %d, %d", id, x, y));
            break;
        }

        return true;
    }

    public void onGlobalLayout() {
        // Get the current width and height of the layout:
        width = layout.getMeasuredWidth();
        height = layout.getMeasuredHeight();        
        Log.i(TAG, String.format("The layout is now (%d x %d)", width , height));

        // (Re)build the string position translation array: 
        touchToString = new int[width];
        for (int x = 0; x < width; x++)
            touchToString[x] = x / (width / NUM_STRINGS);

        // (Re)build the fret position translation array: 
        touchToFret = new int[height];
        for (int y = 0; y < height; y++)
            touchToFret[y] = y / (height / NUM_FRETS);
    }
}
于 2014-04-05T22:18:17.983 回答