IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

1. diel - Vlastné Android komponent - Vytvorenie a usadenie do layoutu

V minulej lekcii, Spinner - Vytvorenie základného roletového menu , sme začali pracovať na projekte ukážkové aplikácie s tromi spinnery. Prvé, používajúci len základné nastavenie, sme zároveň dokončili.

Vitajte u kurzu, v ktorom sa naučíte vytvárať vlastné komponenty pre vaše Android aplikácie v Jave.

Motivácia

Android poskytuje sadu všeobecných komponentov, s ktorými si, väčšinou, vo svojich projektoch vystačíme. Button, EditText, TextView, ProgressBar, ... Občas by sa nám ale iste hodilo, aby nejaká komponenta mala niečo navyše - iný vzhľad alebo iné správanie. Napríklad TextView s vlastným fontom, alebo nejaké špeciálne tlačidlo. A alebo dokonca budeme potrebovať nejakú špeciálnu komponent, ktorá nie je v štandardnej ponuke a ani sa jej žiadna štandardná komponenta nepodobá. Môže to byť napríklad ovládací prvok v prehrávači médií, nejaký graf atď.

Potrebu použiť vlastné komponentu je možné samozrejme vyriešiť aj inak, než vytvorením nového vlastného objektu, ale bude to pravdepodobne znamenať písanie veľkého množstva kódu. To je nevhodné hlavne keď takú komponent budeme chcieť v rozsiahlejšom projekte použiť viackrát.

Vytvorenie vlastnej komponenty

Existujú dva základné spôsoby, ako vytvoriť vlastné komponent:

  • Objekt je priamy potomok triedy View (napr. public class MyView extends View {})
  • Objekt je potomkom už existujúce triedy (napr. public class MyView extends TextView {})

Všetko si budeme ukazovať na konkrétnych príkladoch. Postupovať budeme nasledovne:

  • Vytvoríme XML návrh komponenty
  • Vytvoríme triedu Dedič od triedy View alebo nejakého jej potomka
  • Definujeme parametre pre nastavenie komponenty
  • Vložíme vytvorený XML návrh do layoutu
  • Použijeme vytvorené parametre a nastavení komponenty
  • S kódom budeme pracovať v MainActivity.java

Vlastné textové pole

Začneme vytvorením vlastného poľa pre zadávanie textu. Postupne sa dostaneme aj k zložitejším príkladom. Na nasledujúcom obrázku je vidieť cieľ nášho snaženia:

Vlastné textové pole pre Android v Jave - Vlastné View pre Android aplikácie

Hlavnou súčasťou budúcej komponenty bude EditText, ktorého obsah bude aplikácia pri písaní textu priebežne kontrolovať a zisťovať, či zadaný text zodpovedá nastaveným kritériám. Môžeme kontrolovať napríklad počet zadaných znakov alebo prítomnosť preddefinovaného textového reťazca. Pokiaľ zadaný text nebude spĺňať stanovené požiadavky, bude v pravom dolnom rohu komponenty zobrazený červený varovný text. Obsah tohto textu bude tiež možné nastaviť, rovnako tak i text v hlavičke komponenty.

Ideme teda na to a v Android Štúdiu založíme nový projekt, ktorý pomenujeme CustomInput. Ako prvý vytvoríme XML návrh komponenty.

Xml návrh komponenty

V nasledujúcej ukážke kódu je XML rozvrhnutie budúceho objektu vlastného zadávacieho poľa. V priečinku projektu res/layout/ vytvoríme nový XML súbor pomenovaný my_input.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/my_input_background"
    android:orientation="vertical"
    android:paddingStart="10dp"
    android:paddingLeft="10dp"
    android:paddingTop="10dp"
    android:paddingEnd="10dp"
    android:paddingRight="10dp"
    android:paddingBottom="3dp">

    <TextView
        android:id="@+id/labelTitleText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Text v záhlaví komponenty" >

    </TextView>

    <EditText
        android:id="@+id/etInput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="text" />

    <TextView
        android:id="@+id/labelErrText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:text="Chybová zpráva"
        android:textColor="#C50000"
        android:textSize="12sp"
        android:visibility="invisible" />

</LinearLayout>

Hlavný layout komponenty má nastavené pozadie pomocou odkazu na súbor XML android:background="@drawable/my_input_background". Ten vytvoríme v priečinku projektu res/drawable/. Súbor s pozadím pomenujeme my_input_background.xml a vložíme do neho tento kód:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <solid android:color="#ECECEC" />

    <stroke
        android:width="1dp"
        android:color="#000000"/>

    <corners android:radius="2dp"/>

</shape>

Trieda Dedič od triedy View

Základom každej vlastné komponenty je trieda, ktorá je odvodená, či už priamo alebo nepriamo, od triedy View. Naše ukážkovej zadávacie pole bude dediť od triedy LinearLayout, čo znamená, že nepriamo dedíme od triedy View. Celá hierarchia dedenie vyzerá takto: Object -> View -> ViewGroup -> LinearLayout. Triedu nové komponenty pomenujeme CustomInput a vytvoríme jej v hlavnej zložke projekte java/com.example.custominput/. Základom každej triedy, ktorá je potomkom triedy View, sú štyri preťaženia konstruktoru:

public class CustomInput extends LinearLayout {

    public CustomInput(Context context) {
        super(context);
    }

    public CustomInput(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomInput(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public CustomInput(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
}

Prvý konštruktor je používaný na vytvorenie inštancie objektu pomocou kódu. Ostatné konštruktory sú tu pre objekt konfigurovaný v XML rozvrhnutie.

Ak budete pracovať na projekte, ktorý bude určený pre veľký rozsah verzií systému Android, bude pravdepodobne potrebné k štvrtému konstruktoru pridať anotáciu napr. @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP). Táto anotácia označuje konštruktor použiteľný iba na danej úrovni API alebo vyššej.

Konštruktory určené pre konfiguráciu v XML obsahujú parameter AttributeSet attrs. Zjednodušene povedané sa jedná o kolekciu atribútov, ktoré boli nájdené pri objekte v XML rozvrhnutie a sú v parametri attrs odovzdávané do triedy objektu, kde s nimi môžeme ďalej pracovať.

V okamihu, keď pri písaní vlastnej triedy v hlavičke triedy doplníme extends LinearLayout, nás Android Studio upozorní na nutnosť pridanie konštruktory a samo nám ponúkne ich vygenerovanie.

Parametre pre nastavenie komponenty

Ak budeme chcieť, aby bolo možné nášmu objektu nastavovať nejaké vlastnosti, musíme tieto vlastnosti reprezentovať nejakými atribúty a definovať ich. Teraz si ukážeme, ako na to. Najprv je nutné v resources projekte vytvoriť súbor attrs.xml, ktorého umiestnenie je zrejmé z obrázku:

Vytvorenie resources v Android Studio - Vlastné View pre Android aplikácie

A tu je príklad obsahu súboru attrs.xml pre spomínané zadávacie pole:

<resources>
    <declare-styleable name="CustomInput">
        <attr name="ciText" format="string" />
        <attr name="ciTitleText" format="string" />
        <attr name="ciErrText" format="string" />
        <attr name="ciRequiredText" format="string" />
        <attr name="ciRequiredNumberOfCharacters" format="integer" />
    </declare-styleable>
</resources>

V riadku <declare-styleable name="CustomInput"> je dôležitý atribút name. Ten totiž hrá úlohu v "pomenovávaní" parametrov v triede našej komponenty pri ich získavaní z XML - za chvíľu si to ukážeme.

Poďme sa zoznámiť s práve definovanými atribúty v attrs.xml:

  • ciText - nastavenie východiskového textu pole pre zadávanie textu
  • ciTitleText - nastavenie textu v hlavičke komponenty
  • ciErrText - nastavenie textu červené chybové správy
  • ciRequiredText - znak alebo textový reťazec, ktorý musí zadaný text obsahovať
  • ciRequiredNumberOfCharacters - minimálny požadovaný počet znakov v zadanom texte

Prvé štyri parametre sú typu string, posledný je typu integer. Samozrejme existuje viac dátových typov, ktoré je možné v iných prípadoch použiť. Tu je stručný prehľad použiteľných typov parametrov:

parameter dátový typ
boolean boolean
color @ColorInt int
dimension @LayoutDimension int
dimension @Px int
enum int
flag int
float float
fraction @Fraction (base =?, Pbase =?) Float
integer int
referencie @ AnyRes * int
referencie CharSequence []
referencie ColorStateList
referencie Drawable
referencie Typeface
string CharSequence
string string
string Typeface
  • možno použiť ľubovoľnú anotáciu @...Res

Definované atribúty neskôr (po "Rebuild" projektu) nájdete medzi defaultným parametrami pri konfigurácii zadávacieho poľa v XML v Android Studiu, viď. nasledujúci obrázok:

Atribúty v Android Studio - Vlastné View pre Android aplikácie

Naše nové atribúty začínajú na ci. A to len kvôli prehľadnosti - aby sme ich medzi ostatnými defaultným parametre našli všetky na jednom mieste. V Android Štúdiu sú totiž atribúty zoradené podľa abecedy.

Vloženie vytvoreného XML návrhu do layoutu

Vlastné atribúty použijeme v súboroch XML rozvrhnutie rovnako ako tie defaultný. Jediným rozdielom je, že naše atribúty patrí do inej skupiny. Namiesto toho, aby patrili do http://schemas.android.com/apk/res/android, patrí do http://schemas.android.com/apk/res/[náš_název_balíčku ]. V Android Štúdiu to znamená to, že do nadradeného (alebo do hlavného) layoutu v XML vložíme riadok xmlns:app="http://schemas.android.com/apk/res-auto". Ak na to zabudnete, Android Studio vás na to upozorní.

Náš vlastný atribút potom nebude vložený štýlom android: ... ale app: .... Všimnite si aj názvu našej komponenty v XML - nie je to nič moc pekného, ale má to logiku:-) Nasleduje XML kód layoutu aplikácie, v ktorom je vložená nová komponenta:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.example.custominput.CustomInput
        android:id="@+id/myCustomInput1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        app:ciErrText="Text neobsahuje slovo PES nebo je kratší než 10 znaků!"
        app:ciRequiredNumberOfCharacters="10"
        app:ciRequiredText="pes"
        app:ciTitleText="Zadej text obsahjící slovo PES. Text musí obsahovat minimálně 10 znaků">

    </com.example.custominput.CustomInput>

</LinearLayout>

Takto použité zadávacie pole teda bude požadovať zadanie minimálne desiatich znakov a zároveň, aby vložený text obsahoval reťazec "pes". Kým nebudú obe tieto podmienky splnené, bude zobrazená červená hláška v pravej spodnej časti komponenty. Text tejto chybové hlášky je tiež nastavený v XML. Len poznamenám, že chybová hláška nebude zobrazená v prípade, že textové pole nebude obsahovať žiadny text.

Premenné pre parametre

Na záver tejto časti si vo vytvorenej triede CustomInput deklarujeme premenné a metódy, ktorými neskôr komponentu nastavíme programovo v kóde:

// Proměnné pro reference na jednotlivé komponenty našeho View v XML
TextView labelTitleText;  // Text nad textovým polem
TextView labelErrText;    // Chybová hláška pod textovým polem
EditText etInput;         // Pole pro zadání textu

public void setTitleText(String titleText) {
    this.titleText = titleText;
    this.labelTitleText.setText(titleText);
}

public void setErrText(String errText) {
    this.errText = errText;
    this.labelErrText.setText(errText);
}

public void setRequiredText(String requiredText) {
    this.requiredText = requiredText;
}

V budúcej lekcii, Spinner - Vlastné TextView položky - Java kód , doplníme projekt ukážkové aplikácie o Java kód druhého Spinner, ktorý sa od toho prvého bude líšiť nielen vzhľadom, ale i spôsobom práce s dátami.


 

Predchádzajúci článok
Spinner - Vytvorenie základného roletového menu
Všetky články v sekcii
Vlastné View pre Android aplikácie
Preskočiť článok
(neodporúčame)
Spinner - Vlastné TextView položky - Java kód
Článok pre vás napísal Pavel
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje programování v Javě, hlavně pro Android. Mezi jeho další zájmy patří Arduino, Minecraft.
Aktivity