IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

Multi-touch a ďalšie nové funkcie kreslenia v Jave pre Android

V minulom Android tutoriálu sme si naprogramovali jednoduché kreslenie prstom. Dnes máme sľúbené, že aplikáciu vylepšíme.

Multi-touch

Pretože sme nároční, pridáme si jednoducho možnosť multi-touch, teda kreslenie viacerými prstami naraz. Pomocou nasledujúceho kódu si zistíme koľko prstov je na displeji:

final int pointersCount = event.getPointerCount();

V onTouchEvent() je potom len prejdeme cyklom a priraďujeme ich pozície:

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

Kompletný kód metódy si ukážeme za moment.

Vykreslenie bodky

Možno ste si už všimli, že keď len klikneme prstom, nevykreslí sa bodka, ako by sme možno očakávali. Poďme to napraviť. Vykreslenie bodky jednoducho pridáme do ACTION_DOWN pridaním pohybu o jeden pixel:

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

Celý aktualizovaný kód metódy onTouchEvent() je teraz nasledujúce:

@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;
}

Čistenie plátna

Teraz už sa s tým dá pekne vyhrať :) Teraz si vytvoríme metódu na čistenie plátna. Nazvime ju clearCanvas(). Jednoducho vymažeme súradnice cesty a prekreslíme:

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

Teraz aplikáciu naučíme používať menu. Najprv pridáme do string.xml reťazca "Ukončit" a "Vyčistit", ktoré pomenujeme napr. exit a clear s prefixom menu_. Potom si rozklepneme zložku menu/ a v nej jediný XML súbor. Odmazať existujúce položky a pridáme si vlastné. Kliknutím na add pridáme item.

Napravo v "properties" potom nastavíme len ID a Titulok. Id iba premenujeme na niečo v podobnom duchu, aby sme sa v tom vyznali:

@+id/clear
@+id/exit

A do title vyberieme daný string:

@string/menu_clear
@string/menu_exit

Usporiadanie je možné meniť pomocou tlačidiel UP / DOWN.

Ak teraz klikneme na tlačidlo MENU na telefóne v našej aplikácii, tak sa nám zobrazí menu. Teraz ho zaktivníme. Do hlavnej triedy pridáme metódu onOptionsItemSelected() a do nej nasledujúci 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);
        }
    }

Keď aplikáciu vyskúšame, možno už maľovať, hrať sa s prstami a mazať plátno.

Možnosť výberu farby a hrúbky

Ešte si urobíme možnosť výberu farby a hrúbky, s ktorou budeme kresliť. Do MyCanvas pridáme nasledujúce dve metódy, ktoré tieto vlastnosti nastavujú:

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

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

Pridáme texty a položky do menu. V metóde onOptionsItemSelected() v hlavnej triede si ich potom 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;

Ešte by som rád spomenul, že ak niečo odlazujete a chcete kontrolovať hodnoty alebo jednoducho si niečo vypísať, môžete vypisovať do debug konzoly označené ako LogCat pomocou:

Log.d(tag, msg);

Parameter tag označuje čoho sa zápis týka a msg je potom samotná správa. Oboje sa vypíše do okienka LogCat:

Výsledná Java aplikácie pre kreslenie prstom pre Android - Programovanie Android aplikácií v Jave

Teraz nám aplikácia spĺňa naše minimálne nároky a môžeme si hrať, črtať, kresliť atp.

Určite si sami skúste aplikáciu doplniť napríklad o zmenu pozadia. Skúste si dať maximálne SDK (AndroidManifest.xml) a pridať NumericPicker či ColorPicker. Skúste porozmýšľať ako vyriešiť vracania sa o kroky späť. Ako to urobiť, aby sa pri zmene farby nezmenili všetky čiary. Aby sme pri natočení mobilu nestratili dáta. Pridať možnosť kreslenie kružníc, štvorcov ... Ukladanie a mnohé ďalšie.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 18x (769.24 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Android Java

 

Predchádzajúci článok
Android programovanie - grafický návrh aplikácií
Všetky články v sekcii
Programovanie Android aplikácií v Jave
Článok pre vás napísal Petr Štechmüller
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje primárně programování v Javě, ale nebojí se ani webových technologií.
Aktivity