Poznámka: Tento článek byl založen na verzi Material Components 1.2.0-beta01 do 1. června 2020 .



Během mých tří a půl let práce na malém týmu Androidu ve společnosti HASHTAGS je jednou z hlavních věcí, které mě motivují každý den do práce, svoboda a důvěra naší společnosti řešit problém jakýmkoli způsobem, který považujeme za nejlepší.



Svoboda zkoumat a prozkoumávat mnoho různých řešení problému, který považujeme za nezbytný, a zároveň počítat s časovým rámcem pro dodání aktualizací produktů, nám umožňuje najít nejlepší řešení jak pro naše zákazníky, tak pro náš software.

Jednou z takových výzev bylo vytvoření komponenty uživatelského rozhraní pro naši novou funkci Mobile Reporting. Tato nová součást byla nástrojem pro výběr měsíce, který umožnil našim uživatelům určit rozsah časového období pro analytický přehled.

Výchozí místo, které jsme vybrali, bylo stávající Knihovna materiálových komponent . Spíše než od nuly je tato knihovna aktivně udržována a odpovídá specifikacím materiálu. S touto knihovnou jako základem bychom pravděpodobně mohli snížit množství logiky, kterou bychom museli sami psát.

V tomto článku se budu zabývat tím, jak jsme přistupovali k tomuto procesu, několika jedinečnými faktory při tvorbě aplikace Sprout pro Android, několika „gotchas“, které se během cesty objevily (a byly opraveny) a co vědět, pokud jste pracuje na podobném projektu.

Úvod

Materiálové komponenty pro Android Verze 1.1.0 představila novou komponentu uživatelského rozhraní pro výběr data. Jedno z uvítacích přírůstků tohoto nového MaterialDatePicker přes AppCompat CalendarView je schopnost vybrat rozsah dat pomocí zobrazení kalendáře nebo pole pro zadávání textu.



Starý AppCompat CalendarView nebyl příliš flexibilní. Byla to dobrá součást pro případ omezeného použití, který měl vyřešit; tj. výběrem jednoho data a volitelného minimálního a maximálního data k určení vázaného povoleného časového období.

Nový MaterialDatePicker byl vytvořen s větší flexibilitou, aby umožnil použití rozšířené funkce chování. Funguje prostřednictvím řady rozhraní, která lze implementovat za účelem vylepšení a úpravy chování nástroje pro výběr.

Tato změna chování se provádí za běhu prostřednictvím sady funkcí vzorových sestav na MaterialDatePicker.Builder třída.



To znamená, že jsme schopni rozšířit základní chování tohoto MaterialDatePicker prostřednictvím složitelných komponent rozhraní.

Poznámka: I když existuje řada různých komponent, MaterialDatePicker využívá, v tomto článku se budeme zabývat pouze komponentou Výběr data.


co znamená 131

Výběr časového období

Tým HASHTAGS pro Android byl v procesu budování sekce Analytics Reports.

Tato nová část by našim uživatelům umožnila vybrat sadu filtrů a sadu období, která bude přehled pokrývat.

The MaterialDatePicker přišel s některými předem připravenými komponentami, které jsme mohli využít k provedení našeho případu použití.

V našem nejběžnějším případě, umožňující uživateli vybrat rozsah dat, předpřipravené MaterialDatePicker by stačilo:

S tímto blokem kódu získáme nástroj pro výběr data, který umožňuje uživatelům vybrat časové období.

Měsíční výběr data

Jedním ze přehledů HASHTAGS, který má jedinečnější výběr data, je přehled Twitter Trends.

Tato sestava se liší od ostatních v tom, že namísto povolení jakéhokoli časového období vynucuje výběr jednoho měsíce, což znamená, že uživatel může vybrat pouze březen 2020 vs. 3. března až 16. března 2020.

Naše webová aplikace to zvládá pomocí rozevíracího pole formuláře:

The MaterialDatePicker nemá způsob, jak vynutit takové omezení pomocí předem připraveného nástroje pro výběr časového rozsahu materiálu, který je popsán v předchozí části. Naštěstí byl MaterialDatePicker vytvořen z kompozitních částí, které nám umožňují rozšířit výchozí chování pro náš konkrétní případ použití.

Chování při výběru data

The MaterialDatePicker využívá a DateSelector jako rozhraní použité pro logiku výběru sběrače.

Z Javadoc:

„Rozhraní pro uživatele {@link MaterialCalendar} ovládat, jak kalendář zobrazuje a vrací výběry… “

Všimnete si, že MaterialDatePicker.Builder.dateRangePicker() vrací instanci tvůrce RangeDateSelector, kterou jsme použili ve výše uvedeném příkladu.

Tato třída je předem připravený selektor, který implementuje DateSelector.

Brainstorming chování při výběru data každý měsíc

Pro náš případ použití jsme chtěli způsob, jak nechat uživatelům vybrat celý měsíc jako vybrané časové období; např. Květen 2020, duben 2020 atd.

Mysleli jsme si, že předem připravené RangeDateSelector výše uvedený odkaz nás dostal většinu cesty tam. Komponenta umožnila uživateli vybrat časové období a vynutit a vázaný .

Jediný, co chyběl, byl způsob, jak vynutit výběr, aby se automaticky vybral celý měsíc. Výchozí chování RangeDateSelector má uživatel vybrat počáteční a koncové datum.

Chtěli jsme chování, takže když uživatel vybere den v měsíci, výběr pak automaticky vybere celý měsíc jako časové období.

Řešení, pro které jsme se rozhodli, bylo rozšířit RangeDateSelector a poté přepsat chování při výběru dne a místo toho automaticky vybrat celý měsíc.

Naštěstí existuje funkce, kterou můžeme přepsat z rozhraní DateSelector volal: select(selection: Long).

Tato funkce bude vyvolána, když uživatel vybere den ve výběru, přičemž vybraný den bude z epochy předán v milisekundách UTC.

Implementace chování výběru měsíčního data

Ukázalo se, že implementace je nejjednodušší částí, protože máme jasnou funkci, kterou můžeme přepsat, abychom dosáhli požadovaného chování.

Základní logika bude tato:

  1. Uživatel si vybere den.
  2. The select() funkce je vyvolána s vybraným dnem v a Dlouho UTC milisekundy z epochy.
  3. Najděte první a poslední den měsíce od daného dne, který nám byl předán.
  4. Zavolejte na super.select(1st of month) & super.select(last day of month)
  5. Chování rodičů z RangeDateSelector by mělo fungovat podle očekávání a jako období vyberte měsíc.

Dáme to dohromady

Nyní, když máme vlastní MonthRangeDateSelector, můžeme nastavit naše MaterialDatePicker.

Abychom mohli vzít příklad dále, můžeme výsledek výběru zpracovat takto:

Výsledek bude vypadat takto:

Gotchas

Byl tu jen jeden zásadní problém, který znesnadňoval dospět k tomuto řešení.

Primární komponenty použité k sestavení našich MonthRangeDateSelector byli třídou RangeDateSelector a rozhraní DateSelector. Verze knihovny použitá v tomto článku (1.2.0-beta01) omezila viditelnost těchto dvou souborů, aby zabránila jejich rozšíření nebo implementaci.

Výsledkem je, že i když jsme mohli úspěšně zkompilovat náš nový MonthRangeDateSelector, kompilátor ukázal velmi děsivé varování, které nás od toho odradilo:

Jedním ze způsobů, jak skrýt toto upozornění kompilátoru, je přidat @Suppress('RestrictedApi') jako tak:

Tato zkušenost ilustruje, že i když Knihovna materiálových komponent poskytla komunitě vývojářů Android několik skvělých nových komponent, stále probíhá.

Velkou součástí této knihovny je otevřenost zpětné vazbě od komunity Android! Po zjištění tohoto omezení viditelnosti komponenty jsem otevřel problém na projektu Github, a dokonce otevřel a PR hned to řešit.

Tato otevřená smyčka zpětné vazby mezi týmem Material Components Team a komunitou Android přináší skvělou spolupráci a výsledky pro každého.

Závěr

Nový MaterialDatePicker má některé skvělé funkce po vybalení z krabice, které pravděpodobně pokryjí většinu případů použití výběru data.

Nejlepší část toho, co je podobné AppCompat CalendarView, je však to, že je postaveno skládatelným způsobem. Proto jej lze snadno rozšířit a upravit pro konkrétní případy použití, zatímco v CalendarView by bylo mnohem těžší takové věci dosáhnout.

Zvláštní poděkování

Chtěl bych zdůraznit některé lidi, kteří pomohli recenzovat tento článek:

Sdílej Se Svými Přáteli: