Finn Ut Antall Engel
Ingeniørfag ved Sprout: Bygg en Android-månedsvelger
Merk: Denne artikkelen var basert på versjonen av materialkomponenter 1.2.0-beta01 pr 1. juni 2020 .
I løpet av de tre og et halvt årene jeg jobbet med et lite Android-team på HASHTAGS, er en av de viktigste tingene som motiverer meg til å komme på jobb hver dag, friheten og tilliten fra vårt firma til å takle et problem på den måten vi anser best.
Friheten til å undersøke og utforske mange forskjellige løsninger på et problem vi anser nødvendig, mens vi tar en tidsramme for å levere på produktoppdateringer, gjør at vi kan finne den beste løsningen for både våre kunder og vår programvare.
En slik utfordring innebar å bygge en brukergrensesnittkomponent for vår nye Mobile Reporting-funksjon. Denne nye komponenten var en månedsvelger, som tillot brukerne våre å ramme et datoperiode for en analyserapport.
Startstedet vi valgte var det eksisterende Materialkomponentbibliotek . I stedet for å starte fra bunnen av, vedlikeholdes dette biblioteket aktivt og samsvarer med materialspesifikasjonene. Med dette biblioteket som grunnlag kan vi sannsynligvis redusere mengden logikk vi måtte skrive selv.
I denne artikkelen vil jeg dekke hvordan vi nærmet oss denne prosessen, noen unike faktorer for å bygge Sprout Android-appen, noen få 'gotchas' som kom opp (og ble løst) underveis, og hva du skal vite om du er jobber med et lignende prosjekt.
Introduksjon
Android Material Components 1.1.0 Utgivelse introduserte en ny dato plukker brukergrensesnittkomponent. Et av de velkomne tilleggene til denne nye MaterialDatePicker
over AppCompat CalendarView
er muligheten til å velge et datoperiode ved hjelp av enten en kalendervisning eller et tekstinntastingsfelt.
Den gamle AppCompat CalendarView var ikke veldig fleksibel. Det var en god komponent for den begrensede brukssaken den var ment å løse; det vil si å velge en enkelt dato og valgfrie minimums- og maksimumsdatoer for å spesifisere et tillatt datointervall.
Den nye MaterialDatePicker ble bygget med mer fleksibilitet for å tillate bruk av utvidet funksjonalitet. Det fungerer gjennom en rekke grensesnitt som man kan implementere for å tilpasse og endre plukkerens oppførsel.
Denne atferdsendringen gjøres på kjøretid gjennom et sett med bygningsmønsterfunksjoner på MaterialDatePicker.Builder
klasse.
Dette betyr at vi er i stand til å utvide grunnatferden til dette MaterialDatePicker
gjennom komponerbare grensesnittkomponenter.
Merk: Selv om det er en rekke forskjellige komponenter, MaterialDatePicker
benytter, i denne artikkelen vil vi bare dekke komponenten for valg av dato.
bibelsk betydning av 444
Valg av datoområde
HASHTAGS Android-teamet var i ferd med å bygge vår Analytics Reports-seksjon.
Denne nye delen lar brukerne våre velge et sett med filtre og et sett med datoperioder som rapporten vil dekke.
MaterialDatePicker
kom med noen forhåndsbygde komponenter som vi kunne utnytte for å oppnå brukssaken.
For det vanligste tilfellet vårt, å la brukeren velge et datoperiode, den forhåndsbygde MaterialDatePicker
ville være tilstrekkelig:
Med denne kodeblokken får vi en datovelger som lar brukerne velge et datoperiode.
Månedlig datovelger
En av HASHTAGS-rapportene som har mer unikt datovalg, er Twitter Trends Report.
Denne rapporten skiller seg fra de andre ved at i stedet for å tillate noen form for datointervall, håndhever den en enkelt månedsvalg, noe som betyr at en bruker bare kan velge mars 2020 mot 3. mars til 16. mars 2020.
Webappen vår håndterer dette ved å bruke et rullegardinformularfelt:
MaterialDatePicker
har ikke en måte å håndheve en slik begrensning med den forhåndsbygde Material Date Range Picker diskutert i forrige avsnitt. Heldigvis ble MaterialDatePicker bygget med komponerbare deler som gjør at vi kan utvide standardadferden for vår spesielle brukssak.
Dato valg oppførsel
MaterialDatePicker
utnytter a DateSelector
som grensesnittet som brukes for valglogikken til plukkeren.
Fra Javadoc:
“Grensesnitt for brukere av {@link MaterialCalendar}
for å kontrollere hvordan kalenderen viser og returnerer valg ... ”
Du vil merke at MaterialDatePicker.Builder.dateRangePicker()
returnerer en byggeinstans av RangeDateSelector
, som vi brukte i eksemplet ovenfor.
Denne klassen er en forhåndsbygd velger som implementerer DateSelector
.
Brainstorming en månedlig valg av datovalg
For vårt brukstilfelle ønsket vi en måte å få brukerne våre til å velge en hel måned som valgt datointervall; f.eks. Mai 2020, April 2020, etc.
Vi trodde at den ferdigbygde RangeDateSelector
referert til ovenfor fikk oss det meste av veien dit. Komponenten tillot en bruker å velge et datoperiode og håndheve en bundet .
Det eneste som manglet var en måte å håndheve et utvalg for å automatisk velge hele måneden. Standard oppførsel av RangeDateSelector
har brukeren velge startdato og sluttdato.
Vi ønsket atferd slik at når en bruker velger en dag i måneden, velger velgeren automatisk hele måneden som datoperiode.
Løsningen vi bestemte oss for var å utvide RangeDateSelector
og overstyr deretter valg av dagvalg for å automatisk velge hele måneden i stedet.
Heldigvis er det en funksjon vi kan overstyre fra grensesnittet DateSelector
kalt: select(selection: Long)
.
Denne funksjonen vil bli påkalt når en bruker velger en dag i plukkeren, med den valgte dagen passert i UTC millisekunder fra epoken.
Implementering av en månedlig oppføringsdato
Implementeringen viste seg å være den enkleste delen, siden vi har en klar funksjon vi kan overstyre for å få den oppførselen vi ønsker.
Den grunnleggende logikken vil være denne:
- Bruker velger en dag.
select()
funksjon påkalles med den valgte dagen i a Lang UTC millisekunder fra epoken.- Finn den første og siste dagen i måneden fra den gitte dagen gått til oss.
- Ring til
super.select(1st of month)
&super.select(last day of month)
- Foreldrenes atferd fra
RangeDateSelector
skal fungere som forventet, og velg måneden som datoperiode.
Sette alt sammen
Nå som vi har tilpasset MonthRangeDateSelector
, kan vi sette opp MaterialDatePicker
.
For å ta eksemplet videre kan vi behandle resultatet av valget slik:
Resultatet vil se slik ut:
Gotchas
Det var bare ett hovedproblem som gjorde det vanskelig å komme fram til denne løsningen.
De primære komponentene som ble brukt til å bygge vår MonthRangeDateSelector
var klassen RangeDateSelector
og grensesnittet DateSelector
. Versjonen av biblioteket som ble brukt i denne artikkelen (1.2.0-beta01) begrenset synligheten til disse to filene for å motvirke utvidelse eller implementering av dem.
Som et resultat, selv om vi med hell kunne kompilere den nye MonthRangeDateSelector
, viste kompilatoren en veldig skummel advarsel for å motvirke oss fra å gjøre det:
En måte å skjule denne kompilatorvarselen på er å legge til en @Suppress('RestrictedApi')
som så:
Denne erfaringen illustrerer hvordan, selv om Material Components Library har levert noen flotte nye komponenter til Android Developer Community, er det fortsatt et pågående arbeid.
En stor del av dette biblioteket er åpenheten for tilbakemeldinger fra Android-fellesskapet! Etter å ha oppdaget denne komponentens siktbegrensning, åpnet jeg en utgave på Github-prosjektet, og til og med åpnet en PR for å ta tak i det med en gang.
Denne åpne tilbakemeldingssløyfen mellom Material Components Team og Android Community gir et godt samarbeid og resultater for alle.
Konklusjon
Den nye MaterialDatePicker
har noen gode funksjoner som ikke kommer ut av boksen som sannsynligvis vil dekke de fleste bruksområder for datovalg.
Den beste delen av det over noe som AppCompat CalendarView er imidlertid at det er bygget på en komponerbar måte. Derfor kan den lett utvides og modifiseres for spesifikke bruksområder, mens det ville være mye vanskeligere å oppnå slike ting i CalendarView
.
Spesiell takk
Jeg vil trekke frem noen som hjalp fagfellevurderingen av denne artikkelen:
- Nick Rout ( Github )
- Mike Wolfson ( Github )
- Ryan Phillips ( LinkedIn )
- Lucas Moellers ( Github )
- Med patel ( LinkedIn )
Del Med Vennene Dine: