Setkávám se často s dotazy jak se tvoří takzvaný „preloader aplikace“. Preloader je v podstatě grafické znázornění průběhu spouštění aplikace, kdy jsou vytvářeny instance objektů, určené pro pozdější použití. Z toho už je jasné, že preloader aplikace bude sledovat a znázorňovat činnost konstruktoru. Ukážeme si jeden ze způsobů jak vytvořit svůj vlastní, osobitý a efektní preloader.

Pro náš preloader použijeme potomka třídy Canvas. Nazveme jej například PreloadScreen. Tato třída bude zajišťovat grafické zobrazení průběhu spouštění. Jelikož se jedná o nízkoúrovňovou komponentu, je jasné, že se o vykreslování budeme starat sami. To ale není na škodu, naopak, budeme to brát jako výhodu. Za okamžik pochopíte proč.

Podstata funkce preloaderu spočívá v jeho volání mezi jednotlivými kroky vytváření všech objektů aplikace. Tím je zajištěno sledování průběhu vytváření aplikace. Jak to celé funguje si ukážeme na vzorové aplikaci. Ta sice sama o sobě nic neumí, ale pro náš účel bude naprosto vyhovující.

Volání a posun preloaderu začleníme do jediné funkce. Pojmenujeme ji například increase(). Tato funkce bude pak volána během vytváření jednotlivých částí aplikace v konstruktoru. Obsahuje jen zvýšení hodnoty proměnné load a volání překreslení displeje. Příklad může vypadat takto:

int load = 0;
Canvas can = new PreloadScreen(this);
public void increase() {
  load++;
  can.repaint(osa_x, osa_y, sirka, vyska);
}

Parametry u metody repaint udávají, jaká část displeje se má znovu překreslit podle aktuálních dat. Překreslování celého displeje by spouštění aplikace jen zdržovalo a navíc to ani není nutné. Překreslení tedy proběhne jen v místě, kde je vykreslen ukazatel průběhu spouštění aplikace. O vlastní vykreslení ukazatele průběhu se stará třída PreloadScreen, která rozšiřuje třídu Canvas. V tomto příkladu si vytvoříme horizontální preloader pro displej o velikosti 101×80 pixelů.

Preloader 101x80
Návrh preloaderu pro display 101×80 pixelů

Pro tento návrh preloaderu, určeného na displej o velikosti 101×80 pixelů, by vypadala metoda increase() následovně:

int load = 0;
Canvas can = new PreloadScreen(this);
public void increase() {
  load++;
  /** metoda repaint obsahuje parametry podle kterých vykreslí znovu
  *jen část displeje, kde je vykreslený preloader
  */
  can.repaint(15, 50, 70, 10);
}

Takto potom vypadá preloader v akci:

Preloader
Preloader v akci

A teď si vysvětlíme, jak a co dělá třída PreloadScreen. Tato třída je potomkem třídy Canvas. Nejprve vyplní displej bílým pozadím, na které pak nakreslí černý rámeček podle předlohy. V příkladu jde o obdélník o rozměrech 70×10 pixelů. (Samozřejmě, že můžeme použít jiný tvar nebo barvu. To je výhoda nízkoúrovňové komponenty. V tomto příkladu je použit nejjednodušší typ preloaderu, rámeček s výplní.) Do tohoto obdélníku je pak nakreslen vlastní preloader, neboli vybarvený obdélník. Jeho šířku udává parametr nastavený metodou increase(). Třída PreloadScreen obsahuje následující kód:

import javax.microedition.lcdui.*;
public class PreloadScreen extends Canvas {
  Preloader midlet;
  public PreloadScreen(Preloader midlet) {
    /** V konstruktoru předáme odkaz na třídu Preloader
    */
    this.midlet = midlet;
  }
  public void paint(Graphics g) {
    /** Nastavíme barvu na bílou a vybarvíme takto displej
    */
    g.setColor(255, 255, 255);
    g.fillRect(0, 0, getWidth(), getHeight());
    /** Poté nastavíme barvu na černou a vykreslíme rámeček preloaderu,
    * přidáme nadpis a poté i obsah preloaderu, který závisí na hodnotě proměnné load.
    */
    g.setColor(0, 0, 0);
    g.drawString(„Loading …“, 20, 20, g.TOP|g.LEFT);
    g.drawRect(15, 50, 70, 10);
    g.fillRect(15, 50, midlet.load, 10);
  }
}

Tak a teď už jen zbývá vysvětlit, odkud vlastně voláme metodu increase(), která obsluhuje preloader. Tuto metodu totiž voláme z různých míst konstruktoru. Zpravidla ji voláme vždy po vytvoření instance nějakého objektu tak, aby průběh preloaderu odpovídal průběhu zavádění aplikace do paměti. Pro lepší ilustraci zde uvedu kousek ze zdrojového kódu příkladu:

  public Preloader() {
    disp = Display.getDisplay(this);
    can = new PreloadScreen(this);
    disp.setCurrent(can);
    splash = new Splash(this);
    increase();    // 1
    cmd_back = new Command(„Zpet“, Command.BACK, 1);
    increase();    // 2
    si_help = new StringItem(„Napoveda“, „Toto je jen testovaci aplikace….“);
    increase();    // 3
    si_info = new StringItem(„Info“, „Testovaci aplikace pro demonstraci…..“);
    increase();    // 4
    frm_help = new Form(„Napoveda“);
    frm_help.append(si_help);
    frm_help.addCommand(cmd_back);
    increase();    // 5
    frm_info = new Form(„Info“);
    frm_info.append(si_info);
    frm_info.addCommand(cmd_back);
    increase();  //  6

Jak vidíte, je praktické označit si každé volání metody increase() pořadovým číslem. Po sestavení celého konstruktoru si pak můžeme lehce spočítat, z kolika skoků se náš preloader bude skládat a jak tedy máme rozvrhnout jeho růst. V tomto příkladu jsem použil dvanáct skoků. Abych dosáhl naplnění preloaderu o šířce 70 pixelů, zvolil jsem šesti pixelový skok. Počet pixelů na jeden skok je číslo, o které je zvětšována proměnná load. Tím mám zajištěn optimální rozklad jednotlivých částí konstruktoru na zobrazené skoky. Metoda increase() po úpravě vypadá následovně:

  public void increase() {
    if(load<69) { load+=6; } else { load=70; }
    can.repaint();
  }

Popsaným způsobem lze sledovat vytváření prakticky všech součástí aplikace v konstruktoru a tím zobrazit skutečný průběh spouštění aplikace. Samozřejmě, že preloader nemusí být nutně horizontálně orientovaný obdélník. V tom se meze fantazii tvůrců mobilních aplikací nekladou. Je možno vytvořit preloadery coby stoupající sloupce, zvětšující se kruhy nebo dokonce naopak mizející obrazce. V případě barevných displejů se navíc nabízí možnost preloader obarvit v závislosti na stavu spouštěné aplikace. Dokonce není ani vyloučeno použití několika indikátorů spouštění aplikace najednou. To už závisí jen na úvaze programátora.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět