Metoda onDraw w Androidzie – DSP#10

Aplikacje s艂u偶膮ce do rysowania palcem po ekranie to jeden z pierwszych, kt贸re piszemy przechodz膮c samouczki (przynajmniej te, na platformy mobilne). Co ciekawe, w Androidze zar贸wno tworzenie widok贸w jak i rysowanie palcem jest obs艂ugiwane przez ten sam zestaw klas. W przypadku rysowania mamy p艂贸tno, obiekt p臋dzla i metod臋 typu onTouch(). W przypadku tworzenia widok贸w metody narysuj kwadrat, narysuje lini臋, etc..

Wsp贸ln膮 dla obu tych podej艣膰 jest metoda聽onDraw(), kt贸ra jak sama nazwa wskazuje s艂u偶y do rysowania.聽A tak wygl膮daj膮 efekty moich ostatnich prac:

Istna sztuka wsp贸艂czesna, jak by co mo偶na sk艂ada膰 oferty 馃槈 A teraz co si臋 tutaj w艂a艣ciwie dzieje? T艂o tego widoku pochodzi z klasy MainActivity, w kt贸rej wszystko testuj臋:

Z kolei ten r贸偶owy kolor pochodzi z pliku xml definiuj膮cego layout, r贸wnie偶 w testowej aplikacji:

Nie przetestowa艂em jeszcze wszystkich atrybut贸w, na to b臋dzie czas p贸藕niej, ale p贸ki co z umiarkowanym optymizmem mo偶na za艂o偶y膰, 偶e b臋dzie dobrze.

A teraz przejd藕my do mi臋ska, wklejam kod odpowiedzialny za narysowanie tych fragment贸w:

Do g贸ry zosta艂y zdefiniowane nowe obiekty typu Paint, kt贸re b臋d膮 odpowiada艂y za w艂a艣ciwo艣ci graficzne wszystkich obiekt贸w tego widoku, poni偶ej znajduj膮 si臋 kolory, kt贸re ju偶 pokazywa艂em, ale tym razem zosta艂y rozbudowane o settery. Tzn settery dla tych obiekt贸w istnia艂y ca艂y czas, ale w momencie dodania poni偶ej zmiennej dyrektywy set, mo偶na napisa膰 zmodyfikowany setter. W moim znajduje si臋 dyrektywa field = value kt贸ra oznacza przypisz warto艣膰 do pola. Nie musimy podawa膰 nazwy pola, mam zdefiniowane w Kotlinie s艂贸wko field. Nast臋pnie definiujemy kolor obiektowi typu Paint. A tak偶e wywo艂ujemy invalidate() kt贸re jest odpowiedzialne za ponowne narysowanie obiekt贸w. Tutaj uwaga, kt贸r膮 b臋d臋 musia艂 doda膰 do readme projektu, w przypadku gdyby te operacje odbywa艂y si臋 po za w膮tkiem UI (g艂贸wnym w Androidzie) nale偶y wywo艂a膰 metod臋 postInvalidate(). Kolejnym nowym elementem jest metoda init() wywo艂ywana w konstruktorze. U偶ycie jej jest zalecane, poniewa偶 metoda onDraw()聽mo偶e by膰 wywo艂ywana bardzo cz臋sto i dlatego tworzenie w niej za ka偶dym razem obiekt贸w typu Paint聽mog艂oby negatywnie wp艂yn膮膰 na wydajno艣膰. W ciele metody init znajduje si臋 przypisywanie parametr贸w obiektom Paint, ta metoda na pewno zostanie jeszcze rozbudowana.

Przejd藕my do samego rysowania, odpowiada za to ten kawa艂ek kodu:

Metoda drawPaint() odpowiada po prostu za rysowanie zgodnie z wytycznymi znajduj膮cymi si臋 w obiekcie Paint. Dzi臋ki temu jest idealna do np, wype艂nienia t艂a. Z kolei drawRect() rysuje prostok膮ty, natomiast drawRectF() prostok膮ty z zaokr膮glonymi rogami.聽S膮 2 powody, dla kt贸rych nie mog臋 u偶y膰 tej metody:

  • Adnotacja „NewApi” oznacza tyle, 偶e ta metoda nie jest kompatybilna ze wszystkimi wersjami androida dla kt贸rych udost臋pni臋 bibliotek臋 (z dokumentacji wynika, 偶e ta metoda pojawi艂a si臋 w API 21)
  • Ta metoda rysuje zaokr膮glenia do g贸ry i na dole, a ja potrzebowa艂 bym tylko do g贸ry.

Tym problemem zajm臋 si臋 w nast臋pnych tygodniach, jak i tym, 偶eby prawid艂owo obs艂ugiwa膰 rozmiary i ustawienia element贸w, do czego s艂u偶膮 metody onSizeChanged() oraz onMeasure().

To tyle, je艣li chodzi o podstawy rysowania w Androidzie. Ca艂o艣膰 zosta艂a zaccomitowana jako „drawing” i wszystkie bie偶膮ce zmiany mo偶na podejrze膰 na githubie pod tym linkiem.

  • Te settery w ten spos贸b definiowane to nadpisuj膮 settera na konkretnej instancji obiektu, dobrze rozumiem ? W sensie na przypisaniu warto艣ci do tej jednej zmiennej ?

    • migellal

      Tak, w艂a艣nie tak to dzia艂a 馃槈 Za darmo w Kotlinie dostajesz setter o kodzie: „field = value” Je艣li chcesz co艣 wi臋cej, to piszesz set pod warto艣ci膮 i definiujesz sobie co tam potrzeba. Dodatkowo ukrycie settera, albo gettera uzyskamy przez dodanie modyfikatora private przed get lub set.