Сделать части изображения кликабельными для гитарных табулатур в приложении для Android

Поэтому я хочу сделать простой сенсорный экран для создания гитарных табулатур для Android, но я действительно не знаю, какой метод использовать. Я довольно новичок в написании приложений, но я доволен Java. Гитарная лада будет выглядеть примерно так. http://upload.wikimedia.org/wikipedia/commons/3/37/Guitar_Fretboard_Open_Strings_Diagram.png

1) Сначала я склонялся к созданию кнопок для каждой струны и ладу, но я подумал, что это может быть немного сложно, учитывая, что на гитаре 24 лада плюс 6 струн (144 кнопки), и каждый раз, когда нажимали кнопку, она обновлялась и массив, который имеет 6 строк и количество столбцов х. Я бы поместил кнопки на изображении на лады и сделал бы их невидимыми, но расположение кнопок может быть сложным, и они могут не масштабироваться так, как мне бы хотелось.

Массив будет очень удобен для хранения значений, потому что табулатура написана так...

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

номера ладов написаны в.

Я даже не уверен, с чего начать этот метод. Должен ли я иметь отдельный метод для каждой кнопки, потому что все они имеют разные значения? Чтобы получить значение от кнопки к массиву, мне нужно было бы поставить что-то вроде

strArray [число, п]

где count - это переменная вне метода, а n - это переменная, которая возвращается при нажатии кнопки. Счет будет увеличен или уменьшен с помощью следующей / предыдущей кнопки, чтобы он мог пройти массив

2) Я смотрел на этот метод http://blahti.wordpress.com/2012/06/26/images-with-clickable-areas/ и похоже, что он может работать, но разработчик использовал цвета, чтобы сообщать различные горячие спот, и я подумал, что это, вероятно, будет невозможно, учитывая, что мне понадобится 144 разных цвета

Есть ли более простой способ, чтобы я мог реализовать это вместо этого?

Извините, если я не очень хорошо объяснил, я новичок в разработке на Android и у меня много вопросов.

1 ответ

Концептуально легко было бы использовать невидимые кнопки поверх большого фона, но у вас были бы проблемы масштабируемости, о которых вы упоминали. Он также не очень хорошо справляется с распознаванием нескольких одновременных касаний. Суть второго подхода, использующего касание, - это, вероятно, то, что вы хотите. MotionEvent в методе onTouch() предоставит вам местоположение и действие касаний. Тогда это просто становится упражнением в переводе координаты точки, которой коснулись / переместили / подняли, с соответствующим ладом или струной.

Есть много приличных учебных пособий по распознаванию касаний. Вот один

Редактировать:

Есть несколько способов перевода между позицией касания и желаемой струной и раздражением. Одним из способов является просто сделать расчеты strng = x / (width / NUM_STRINGS) а также fret = y / (height / NUM_FRETS) для каждого сенсорного события. (Предполагая, что строки отображаются на дисплее вдоль.)

Другой простой способ - создать и использовать таблицы поиска для перевода. Это требует нескольких тысяч байт для хранения целых чисел, но позволяет выполнить пару быстрых поисков в массиве, чтобы определить строку и раздражение.

Вот пример деятельности, которая реализует последний подход. Он содержит некоторые предположения и ярлыки, но основные функциональные возможности должны быть достаточно надежными. Только событие вниз показывает перевод; Вы также захотите сделать что-то подходящее для событий 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);
    }
}
Другие вопросы по тегам