PHP týden Předvánoční slevová akce
Pouze tento týden sleva až 80 % na PHP e-learning!
Využij předvánočních slev a získej od nás 20 % bodů zdarma! Více zde

Multi-touch a další nové funkce kreslení v Javě pro Android

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulém Android tutoriálu jsme si naprogramovali jednoduché kreslení prstem. Dnes máme slíbeno, že aplikaci vylepšíme.

Multi-touch

Protože jsme nároční, přidáme si jednoduše možnost multi-touche, tedy kreslení více prsty najednou. Pomocí následujícího kódu si zjistíme kolik prstů je na displeji:

final int pointersCount = event.getPointerCount();

V onTouchEvent() je poté jen projedeme cyklem a přiřazujeme jejich pozice:

for (int p = 0; p < pointersCount; p++) {
    xPos = event.getX(p);
    yPos = event.getY(p);
    ...
}

Kompletní kód metody si ukážeme za moment.

Vykreslení tečky

Možná jste si již všimli, že když pouze klepneme prstem, nevykreslí se tečka, jak bychom možná očekávali. Pojďme to napravit. Vykreslení tečky jednoduše přidáme do ACTION_DOWN přidáním pohybu o jeden pixel:

path.lineTo(xPos + 1, yPos + 1);

Celý aktualizovaný kód metody onTouchEvent() je nyní následující:

@Override
public boolean onTouchEvent(MotionEvent event) {
    // Inicializace proměnných pro ukládání pozice dotyku
    float xPos;
    float yPos;
    // Počet prstů, kterými se dotýkáme obrazovky. Maximum je (asi v závislosti na zařízení) limitováno na 4
    final int pointersCount = event.getPointerCount();

    // Projede všechny pointery - umožňuje multi-touch
    for (int p = 0; p < pointersCount; p++) {
        xPos = event.getX(p);
        yPos = event.getY(p);
        // Zpracování akcí
        switch (event.getAction()) {
            // Při dotyku, se vyresetuje výchozí pozice
            case MotionEvent.ACTION_DOWN:
                path.moveTo(xPos, yPos);
                path.lineTo(xPos + 1, yPos + 1);
                break;

            // Při pohybu nebo opuštění obrazovky
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_UP:
                // Nastaví se současné souřadnice
                path.lineTo(xPos, yPos);
                break;
        }
    }

    // Překreslení
    invalidate();

    return true;
}

Čištění plátna

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Teď už se s tím dá pěkně vyhrát :) Nyní si vytvoříme metodu na čištění plátna. Nazvěme ji clearCanvas(). Jednoduše vymažeme souřadnice cesty a překreslíme:

public void clearCanvas() {
    path.reset();
    invalidate();
}

Nyní aplikaci naučíme používat menu. Nejprve přidáme do string.xml řetězce "Ukončit" a "Vyčistit", které pojmenujeme např. exit a clear s prefixem menu_. Pak si rozklepneme složku menu/ a v ní jediný XML soubor. Odmažeme stávající položky a přidáme si vlastní. Klepnutím na add přidáme item.

Napravo v "properties" pak nastavíme jen ID a Titulek. Id pouze přejmenujeme na něco v podobném duchu, abychom se v tom vyznali:

@+id/clear
@+id/exit

A do title vybereme daný string:

@string/menu_clear
@string/menu_exit

Uspořádání lze měnit pomocí tlačítek UP/DOWN.

Pokud nyní klepneme na tlačítko MENU na telefonu v naší aplikaci, tak se nám zobrazí menu. Teď jej zaktivníme. Do hlavní třídy přidáme metodu onOptionsItemSelected() a do ní následující kód:

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // získání ID vybrané položky
        switch (item.getItemId()) {
            // Ukončení aplikace
            case R.id.exit:
                this.finish();
                return true;

            // Vyčištění plátna
            case R.id.clear:
                myCanvas.clearCanvas();
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

Když aplikaci vyzkoušíme, lze již malovat, hrát si s prsty a mazat plátno.

Možnost výběru barvy a tloušťky

Ještě si uděláme možnost výběru barvy a tloušťky, se kterou budeme kreslit. Do MyCanvas přidáme následující dvě metody, které tyto vlastnosti nastavují:

public void setPenColor(int color) {
    paint.setColor(color);
    invalidate();
}

public void setPenWidth(float width) {
    paint.setStrokeWidth(width);
    invalidate();
}

Přidáme texty a položky do menu. V metodě onOptionsItemSelected() v hlavní třídě si je pak zaktivníme:

case R.id.pen_width:
    final CharSequence[] sizes = {"1", "3", "5", "10", "15", "20"};

    AlertDialog.Builder sizePickerDialog = new AlertDialog.Builder(this);
    sizePickerDialog.setTitle("Vyber tloušťku:");
    sizePickerDialog.setItems(sizes, new DialogInterface.OnClickListener() {
        // Po zvolení se zobrazí informace o vybrané položce a zavolá se příslušná metoda, která nastaví vybranou vlastnost
        public void onClick(DialogInterface dialog, int item) {
            Toast.makeText(getApplicationContext(), "Vybrána tloušťka: " + sizes[item] + "px", Toast.LENGTH_SHORT).show();
            myCanvas.setPenWidth(Float.valueOf((String) sizes[item]));
        }
    });
    AlertDialog pickSize = sizePickerDialog.create();
    pickSize.show();
    return true;
case R.id.pen_color:
    final Map<String, Integer> colorList = new HashMap<>();
    colorList.put("Černá", Color.BLACK);
    colorList.put("Červená", Color.RED);
    colorList.put("Žlutá", Color.YELLOW);
    colorList.put("Zelená", Color.GREEN);
    colorList.put("Modrá", Color.BLUE);
    colorList.put("Fialová", Color.MAGENTA);
    colorList.put("Šedá", Color.GRAY);

    final CharSequence[] colors = colorList.keySet().toArray(new CharSequence[colorList.size()]);

    // Vytvoření dialogu
    AlertDialog.Builder colorPickerDialog = new AlertDialog.Builder(this);
    colorPickerDialog.setTitle("Vyber barvičku:");
    colorPickerDialog.setItems(colors, new DialogInterface.OnClickListener() {
        // Po zvolení se zobrazí informace o vybrané položce a zavolá se příslušná metoda, která nastaví vybranou vlastnost
        public void onClick(DialogInterface dialog, int item) {
            Toast.makeText(getApplicationContext(), "Vybraná barvička: " + colors[item], Toast.LENGTH_SHORT).show();
            myCanvas.setPenColor(colorList.get(colors[item]));
        }
    });
    AlertDialog pickColor = colorPickerDialog.create();
    pickColor.show();
    return true;

Ještě bych rád zmínil, že pokud něco odlazujete a chcete kontrolovat hodnoty nebo prostě si něco vypsat, můžete vypisovat do debug konzole označené jako LogCat pomocí:

Log.d(tag, msg);

Parametr tag označuje čeho se zápis týká a msg je poté samotná zpráva. Obojí se vypíše do okénka LogCat:

Výsledná Java aplikace pro kreslení prstem pro Android

Nyní nám aplikace splňuje naše minimální nároky a můžeme si hrát, črtat, kreslit atp.

Určitě si sami zkuste aplikaci doplnit například o změnu pozadí. Zkuste si dát maximální SDK (AndroidManifest.xml) a přidat NumericPicker či ColorPicker. Zkuste popřemýšlet jak vyřešit vracení se o kroky zpět. Jak to udělat, aby se při změně barvy nezměnily všechny čáry. Abychom při natočení mobilu neztratili data. Přidat možnost kreslení kružnic, čtverců... Ukládání a mnohé další.


 

Stáhnout

Staženo 5x (769.24 kB)
Aplikace je včetně zdrojových kódů v jazyce Android Java

 

 

Článek pro vás napsal Petr Štechmüller
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Autor se věnuje primárně programování v Jave, ale nebojí se ani webových technologií.
Předchozí článek
Android programování - grafický návrh aplikací
Všechny články v sekci
Programování Android aplikací v Javě
Miniatura
Následující článek
Programujeme Android hru
Aktivity (3)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!