Nyheter i Android, Telefoner, Prylar Och Recensioner

Sprout Engineering: Skapa en Android-månadsväljare

Obs: Den här artikeln baserades på Material Components version 1.2.0-beta01 från och med 1 juni 2020.

Under mina tre och ett halvt år som jag arbetat i ett litet Android-team på Sprout Social, är en av de viktigaste sakerna som motiverar mig att arbeta varje dag friheten och förtroendet hos vårt företag att ta itu med ett problem på det sätt vi tycker är bäst.

Friheten att undersöka och utforska många olika lösningar på ett problem vi anser vara nödvändigt, samtidigt som vi har en tidsram för att leverera produktuppdateringar, gör att vi kan hitta den bästa lösningen för både våra kunder och vår mjukvara.

En av dessa utmaningar var att skapa en UI-komponent för vår nya mobilrapporteringsfunktion. Den här nya komponenten var en månadsväljare, vilket gjorde det möjligt för våra användare att ställa in ett datumintervall för en analytisk rapport.

Utgångsplatsen vi valde var det befintliga materialkomponentbiblioteket. Istället för att börja om från början underhålls det här biblioteket aktivt och anpassas till materialspecifikationerna. Med detta bibliotek som bas skulle vi förmodligen kunna minska mängden logik vi skulle behöva skriva själva.

I den här artikeln kommer jag att täcka hur vi närmade oss denna process, några unika faktorer för att skapa Sprout Android-appen, några “buggar” som uppstod (och fixades) längs vägen, och vad du bör veta om du arbetar med ett projekt liknande.

Introduktion

Android Material Components version 1.1.0 introducerade en ny datumväljare UI-komponent. Ett av de välkomna tilläggen av denna nya MaterialDatePicker över AppCompat CalendarView är möjligheten att välja ett datumintervall med hjälp av en kalendervy eller ett textinmatningsfält.

Den gamla AppCompat CalendarView var inte särskilt flexibel. Det var en bra komponent för det begränsade användningsfallet det var tänkt att lösa; det vill säga, välj ett enstaka datum och valfria lägsta och högsta datum för att ange en tillåten gräns för datumintervall.

Den nya MaterialDatePicker skapades med mer flexibilitet för att möjliggöra användningen av utökad beteendefunktionalitet. Den fungerar genom en serie gränssnitt som kan implementeras för att justera och modifiera väljarens beteende.

Relaterad  17 skäl till varför du behöver InfusionSoft för ditt småföretag

Denna beteendemodifiering görs under körning genom en uppsättning byggmönsterfunktioner i klassen MaterialDatePicker.Builder.

Detta innebär att vi kan utöka basbeteendet för denna MaterialDatePicker genom komponerbara gränssnittskomponenter.

Obs: Även om det finns ett antal olika komponenter som MaterialDatePicker använder, kommer vi i den här artikeln endast att täcka datumväljarkomponenten.

Datumintervallväljare

Sprout Social Android-teamet var i färd med att skapa vår analysrapportsektion.

Detta nya avsnitt skulle tillåta våra användare att välja en uppsättning filter och en uppsättning datumintervall som rapporten skulle täcka.

MaterialDatePicker kom med några förbyggda komponenter som vi kunde utnyttja för att uppnå vårt användningsfall.

För vårt vanligaste fall, att låta en användare välja ett datumintervall, skulle den förbyggda MaterialDatePicker räcka:

Med detta kodblock får vi en datumväljare som låter användare välja ett datumintervall.

Månatlig datumväljare

En av Sprout Social-rapporterna som har ett mer unikt datumval är Twitter Trends Report.

Den här rapporten skiljer sig från de andra genom att istället för att tillåta vilken typ av datumintervall som helst, tillämpar den ett val av en enda månad, vilket innebär att en användare endast kan välja mars 2020 jämfört med 3 mars – 16 mars 2020.

Vår webbapplikation hanterar detta med hjälp av ett rullgardinsfält:

MaterialDatePicker har inte ett sätt att upprätthålla en sådan begränsning med den förbyggda Material Date Range Picker som diskuterades i föregående avsnitt. Lyckligtvis byggdes MaterialDatePicker med komponerbara delar som tillåter oss att utöka standardbeteendet för vårt specifika användningsfall.

Beteende för datumval

MaterialDatePicker använder en DateSelector som gränssnittet som används för väljarvalslogiken.

Från Javadoc:

“Gränssnitt för {@link MaterialCalendar}-användare för att styra hur kalendern visas och returnerar val…”

Du kommer att märka att MaterialDatePicker.Builder.dateRangePicker() returnerar en builder-instans av RangeDateSelector, som vi använde i exemplet ovan.

Den här klassen är en förbyggd väljare som implementerar DateSelector.

Brainstorma ett månatligt datumvalsbeteende

För vårt användningsfall ville vi ha ett sätt för våra användare att välja en hel månad som ett valt datumintervall; till exempel maj 2020, april 2020 osv.

Relaterad  Underhåll ditt skägg med laserprecision – Ny Philips Skäggtrimmer 9000

Vi tror att den förbyggda RangeDateSelector som refereras till ovan tog oss det mesta på vägen. Komponenten gjorde det möjligt för en användare att välja ett datumintervall och tillämpa en [lower, upper] bunden.

Det enda som saknades var ett sätt att genomdriva ett urval för att automatiskt välja hela månaden. Standardbeteendet för RangeDateSelector gör att användaren väljer ett startdatum och ett slutdatum.

Vi ville ha ett beteende så att när en användare valde en dag i månaden, skulle väljaren automatiskt välja hela månaden som datumintervall.

Lösningen vi bestämde oss för var att utöka RangeDateSelector och sedan åsidosätta beteendet för val av dag för att automatiskt välja hela månaden.

Lyckligtvis finns det en funktion som vi kan åsidosätta från DateSelector-gränssnittet som heter: select(selection: Long).

Denna funktion kommer att anropas när en användare väljer en dag i väljaren, där den valda dagen har förflutit i UTC-millisekunder sedan epoken.

Implementera ett beteende för val av månadsdatum

Implementeringen visade sig vara den enklaste delen, eftersom vi har en tydlig funktion som vi kan åsidosätta för att få det beteende vi vill ha.

Den grundläggande logiken blir denna:

  1. Användaren väljer en dag.
  2. Funktionen select() anropas med dagen vald i a Lång UTC millisekunder sedan epok.
  3. Hitta den första och sista dagen i månaden från den givna dagen som hände oss.
  4. Ring ett samtal till super.select (första dagen i månaden) och super.select (sista dagen i månaden)
  5. Huvudbeteendet för RangeDateSelector bör fungera som förväntat och välj månad som datumintervall.

Få alltid att falla på plats

Nu när vi har vår anpassade MonthRangeDateSelector kan vi konfigurera vår MaterialDatePicker.

För att ta exemplet vidare kan vi bearbeta urvalsresultatet så här:

Resultatet kommer att se ut så här:

Gotchas

Det fanns bara ett stort problem som gjorde det svårt att nå denna lösning.

Huvudkomponenterna som användes för att bygga vår MonthRangeDateSelector var RangeDateSelector-klassen och DateSelector-gränssnittet. Den version av biblioteket som används i den här artikeln (1.2.0-beta01) begränsade synligheten för dessa två filer, för att motverka deras förlängning eller implementering.

Relaterad  IPhone 2019: Apple kan lansera 5 modeller, varav två med trippelfotosensor

Som ett resultat, även om vi lyckades kompilera vår nya MonthRangeDateSelector, visade kompilatorn en mycket skrämmande varning för att avskräcka oss från att göra det:

Ett sätt att dölja denna varning från kompilatorn är att lägga till en @Suppress(“RestrictedApi”) så här:

Den här erfarenheten illustrerar hur, även om Material Components Library har tillhandahållit några fantastiska nya komponenter till Android-utvecklargemenskapen, det fortfarande pågår.

En stor del av det här biblioteket är öppenheten för feedback från Android-gemenskapen. Efter att ha upptäckt denna begränsning av komponentsynlighet, öppnade jag ett problem på Github-projektet och öppnade till och med en PR för att ta itu med det omedelbart.

Denna öppna återkopplingsslinga mellan Material Components-teamet och Android-gemenskapen skapar fantastiskt samarbete och resultat för alla.

Slutsats

Den nya MaterialDatePicker har några fantastiska funktioner som är klara i lådan som förmodligen kommer att täcka de flesta användningsfall för datumplockning.

Det bästa med något som AppCompat CalendarView är dock att det är byggt på ett komponerbart sätt. Så det kan enkelt utökas och modifieras för specifika användningsfall, medan det skulle vara mycket svårare att uppnå sådana saker i CalendarView.

Speciellt tack

Jag skulle vilja lyfta fram några personer som hjälpte till att granska den här artikeln: