Σημείωση: Αυτό το άρθρο βασίστηκε στην έκδοση Material Components 1.2.0-beta01 από 1 Ιουνίου 2020 .





Στα τριάμισι χρόνια που εργάζομαι σε μια μικρή ομάδα Android στο HASHTAGS, ένα από τα βασικά πράγματα που με παρακινούν να εργάζομαι καθημερινά είναι η ελευθερία και η εμπιστοσύνη από την εταιρεία μας να αντιμετωπίζω ένα πρόβλημα με οποιονδήποτε τρόπο θεωρούμε καλύτερα.



Η ελευθερία να ερευνούμε και να διερευνούμε πολλές διαφορετικές λύσεις σε ένα πρόβλημα που θεωρούμε απαραίτητο, ενώ μελετάμε ένα χρονικό πλαίσιο για την ενημέρωση των προϊόντων, μας επιτρέπει να βρούμε την καλύτερη λύση τόσο για τους πελάτες μας όσο και για το λογισμικό μας.



Μια τέτοια πρόκληση αφορούσε τη δημιουργία ενός στοιχείου διεπαφής χρήστη για τη νέα μας δυνατότητα αναφοράς κινητών. Αυτό το νέο στοιχείο ήταν ένα εργαλείο επιλογής μήνα, το οποίο επέτρεψε στους χρήστες μας να καλύπτουν ένα εύρος ημερομηνιών για μια αναφορά αναλυτικών στοιχείων.

Το σημείο εκκίνησης που επιλέξαμε ήταν το υπάρχον Βιβλιοθήκη συστατικών υλικών . Αντί να ξεκινά από το μηδέν, αυτή η βιβλιοθήκη διατηρείται ενεργά και ευθυγραμμίζεται με τις προδιαγραφές Υλικού. Με αυτήν τη βιβλιοθήκη ως θεμέλιο, θα μπορούσαμε πιθανώς να μειώσουμε τον όγκο της λογικής που πρέπει να γράψουμε οι ίδιοι.

Σε αυτό το άρθρο, θα καλύψω τον τρόπο με τον οποίο προσεγγίσαμε αυτήν τη διαδικασία, μερικούς μοναδικούς παράγοντες για τη δημιουργία της εφαρμογής Sprout Android, μερικές «gotchas» που εμφανίστηκαν (και επιδιορθώθηκαν) στην πορεία και τι να ξέρετε αν είστε δουλεύοντας σε ένα παρόμοιο έργο.



Εισαγωγή

Τα συστατικά υλικού Android 1.1.0 Έκδοση εισήγαγε ένα νέο στοιχείο UI επιλογής ημερομηνιών. Μία από τις ευπρόσδεκτες προσθήκες αυτού του νέου MaterialDatePicker πάνω από το AppCompat CalendarView είναι η δυνατότητα επιλογής ενός εύρους ημερομηνιών χρησιμοποιώντας είτε Προβολή ημερολογίου είτε πεδίο εισαγωγής κειμένου.



Το παλιό AppCompat CalendarView δεν ήταν πολύ ευέλικτο. Ήταν ένα καλό συστατικό για την περίπτωση περιορισμένης χρήσης που είχε σκοπό να επιλύσει. δηλαδή, επιλέγοντας μία ημερομηνία και προαιρετικές ελάχιστες και μέγιστες ημερομηνίες για να καθορίσετε ένα επιτρεπόμενο όριο ημερομηνιών.

Το νέο MaterialDatePicker δημιουργήθηκε με μεγαλύτερη ευελιξία για να επιτρέπει τη χρήση εκτεταμένης λειτουργικότητας συμπεριφοράς. Λειτουργεί μέσω μιας σειράς διεπαφών που μπορεί κανείς να εφαρμόσει για να τροποποιήσει και να τροποποιήσει τη συμπεριφορά του επιλογέα.



Αυτή η τροποποίηση συμπεριφοράς γίνεται κατά το χρόνο εκτέλεσης μέσω ενός συνόλου λειτουργιών μοτίβου δημιουργού στο MaterialDatePicker.Builder τάξη.



Αυτό σημαίνει ότι μπορούμε να επεκτείνουμε τη βασική συμπεριφορά αυτού MaterialDatePicker μέσω συνθετικών στοιχείων διεπαφής.



Σημείωση: Ενώ υπάρχουν διάφορα διαφορετικά στοιχεία, το MaterialDatePicker χρησιμοποιεί, σε αυτό το άρθρο θα καλύψουμε μόνο το στοιχείο επιλογής ημερομηνίας.


22:22 νόημα

Εργαλείο επιλογής εύρους ημερομηνιών

Η ομάδα HASHTAGS Android βρισκόταν στη διαδικασία δημιουργίας της Ενότητας Αναφορών Analytics.

Αυτή η νέα ενότητα θα επέτρεπε στους χρήστες μας να επιλέξουν ένα σύνολο φίλτρων και ένα σύνολο εύρους ημερομηνιών που θα καλύπτει η αναφορά.

Το MaterialDatePicker ήρθε με μερικά προ-κατασκευασμένα στοιχεία που θα μπορούσαμε να αξιοποιήσουμε για να ολοκληρώσουμε τη θήκη χρήσης μας.

Για την πιο συνηθισμένη μας περίπτωση, επιτρέποντας σε έναν χρήστη να επιλέξει ένα εύρος ημερομηνιών, το προ-ενσωματωμένο MaterialDatePicker θα αρκούσε:

Με αυτό το μπλοκ κώδικα, λαμβάνουμε μια Επιλογή ημερομηνίας που επιτρέπει στους χρήστες να επιλέγουν ένα εύρος ημερομηνιών.

Μηνιαίο εργαλείο επιλογής ημερομηνιών

Μία από τις αναφορές HASHTAGS που έχει πιο μοναδική επιλογή ημερομηνίας είναι η αναφορά Twitter Trends.

Αυτή η αναφορά διαφέρει από τις άλλες στο ότι, αντί να επιτρέπει οποιοδήποτε είδος εύρους ημερομηνιών, επιβάλλει μια επιλογή ενός μήνα, πράγμα που σημαίνει ότι ένας χρήστης μπορεί να επιλέξει μόνο τον Μάρτιο 2020 έναντι 3 Μαρτίου έως τις 16 Μαρτίου 2020.

Η εφαρμογή ιστού μας το χειρίζεται χρησιμοποιώντας ένα αναπτυσσόμενο πεδίο φόρμας:

Το MaterialDatePicker δεν έχει τρόπο να επιβάλει έναν τέτοιο περιορισμό με το προ-χτισμένο υλικό επιλογής εύρους ημερομηνιών που συζητήθηκε στην προηγούμενη ενότητα. Ευτυχώς, το MaterialDatePicker κατασκευάστηκε με συνθετικά μέρη που μας επιτρέπουν να επεκτείνουμε την προεπιλεγμένη συμπεριφορά για τη συγκεκριμένη περίπτωση χρήσης.

Συμπεριφορά επιλογής ημερομηνίας

Το MaterialDatePicker μόχλευση a DateSelector ως διεπαφή που χρησιμοποιείται για τη λογική επιλογής του επιλογέα.

Από το Javadoc:

«Διεπαφή για χρήστες {@link MaterialCalendar} για να ελέγξετε τον τρόπο εμφάνισης και επιστροφής των επιλογών του Ημερολογίου… '

Θα παρατηρήσετε ότι η MaterialDatePicker.Builder.dateRangePicker() επιστρέφει μια παρουσία δημιουργού του RangeDateSelector, την οποία χρησιμοποιήσαμε στο παραπάνω παράδειγμα.

Αυτή η τάξη είναι ένας προ-ενσωματωμένος επιλογέας που εφαρμόζει DateSelector.

Καταιγισμός ιδεών για μηνιαία επιλογή επιλογής ημερομηνίας

Για την περίπτωση χρήσης μας, θέλαμε έναν τρόπο να κάνουμε τους χρήστες μας να επιλέξουν έναν ολόκληρο μήνα ως επιλεγμένο εύρος ημερομηνιών. π.χ. Μάιος 2020, Απρίλιος 2020, κ.λπ.

Σκεφτήκαμε ότι το προ-χτισμένο RangeDateSelector Οι παραπάνω αναφορές μας έκαναν το μεγαλύτερο μέρος εκεί. Το στοιχείο επέτρεψε στον χρήστη να επιλέξει ένα εύρος ημερομηνιών και να εφαρμόσει ένα όριο .

Το μόνο πράγμα που έλειπε ήταν ένας τρόπος να επιβληθεί μια επιλογή για αυτόματη επιλογή ολόκληρου του μήνα. Η προεπιλεγμένη συμπεριφορά του RangeDateSelector έχει ο χρήστης να επιλέξει μια ημερομηνία έναρξης και μια ημερομηνία λήξης.

Θέλαμε μια συμπεριφορά έτσι ώστε όταν ένας χρήστης επιλέγει μια ημέρα στον μήνα, ο επιλογέας θα επιλέξει αυτόματα ολόκληρο τον μήνα ως εύρος ημερομηνιών.

Η λύση που αποφασίσαμε ήταν να επεκτείνουμε το RangeDateSelector και στη συνέχεια αντικαταστήστε τη συμπεριφορά επιλογής ημέρας για αυτόματη επιλογή ολόκληρου του μήνα.

Ευτυχώς, υπάρχει μια συνάρτηση που μπορούμε να παρακάμψουμε από τη διεπαφή DateSelector κάλεσε: select(selection: Long).

Αυτή η συνάρτηση θα ενεργοποιηθεί όταν ένας χρήστης επιλέξει μια ημέρα στο εργαλείο επιλογής, με την επιλεγμένη ημέρα να περάσει σε UTC χιλιοστά του δευτερολέπτου από την εποχή.

Εφαρμογή μιας μηνιαίας συμπεριφοράς επιλογής ημερομηνίας

Η υλοποίηση αποδείχθηκε το πιο απλό μέρος, αφού έχουμε μια σαφή λειτουργία που μπορούμε να παρακάμψουμε για να πάρουμε τη συμπεριφορά που θέλουμε.

Η βασική λογική θα είναι αυτή:

  1. Ο χρήστης επιλέγει μια ημέρα.
  2. Το select() η συνάρτηση ενεργοποιείται με την επιλεγμένη ημέρα σε ένα Μακρύς UTC χιλιοστά του δευτερολέπτου από την εποχή.
  3. Βρείτε την πρώτη και τελευταία ημέρα του μήνα από τη δεδομένη ημέρα που μας πέρασε.
  4. Πραγματοποιήστε μια κλήση στο super.select(1st of month) & super.select(last day of month)
  5. Η γονική συμπεριφορά από RangeDateSelector θα πρέπει να λειτουργεί όπως αναμένεται και επιλέξτε το μήνα ως εύρος ημερομηνιών.

Συνδυάζοντας τα όλα μαζί

Τώρα που έχουμε το Custom MonthRangeDateSelector, μπορούμε να ρυθμίσουμε το MaterialDatePicker.

Για να πάρουμε το παράδειγμα περαιτέρω, μπορούμε να επεξεργαστούμε το αποτέλεσμα της επιλογής ως εξής:

Το αποτέλεσμα θα μοιάζει με αυτό:

Γκότσα

Υπήρχε μόνο ένα σημαντικό ζήτημα που έκανε δύσκολη την εξεύρεση αυτής της λύσης.

Τα κύρια συστατικά που χρησιμοποιήθηκαν για την κατασκευή του MonthRangeDateSelector ήταν η τάξη RangeDateSelector και η διεπαφή DateSelector. Η έκδοση της βιβλιοθήκης που χρησιμοποιείται σε αυτό το άρθρο (1.2.0-beta01) περιόρισε την ορατότητα αυτών των δύο αρχείων, για να αποθαρρύνει την επέκταση ή την εφαρμογή τους.

Ως αποτέλεσμα, παρόλο που θα μπορούσαμε να συντάξουμε με επιτυχία το νέο μας MonthRangeDateSelector, ο μεταγλωττιστής έδειξε μια πολύ τρομακτική προειδοποίηση για να μας αποθαρρύνει να το κάνουμε:

Ένας τρόπος απόκρυψης αυτής της προειδοποίησης μεταγλωττιστή είναι να προσθέσετε ένα @Suppress('RestrictedApi') έτσι:

Αυτή η εμπειρία δείχνει πώς, παρόλο που η Βιβλιοθήκη συστατικών υλικών έχει παράσχει μερικά εξαιρετικά νέα στοιχεία στην κοινότητα προγραμματιστών Android, εξακολουθεί να βρίσκεται σε εξέλιξη.

Ένα μεγάλο μέρος αυτής της βιβλιοθήκης είναι το άνοιγμα των σχολίων από την Κοινότητα Android! Αφού ανακάλυψα αυτόν τον περιορισμό ορατότητας, άνοιξα ένα θέμα στο Github Project, και μάλιστα άνοιξε ένα PR για να το αντιμετωπίσουμε αμέσως.

Αυτός ο ανοιχτός βρόχος ανάδρασης μεταξύ της ομάδας υλικών και της κοινότητας Android δημιουργεί εξαιρετική συνεργασία και αποτελέσματα για όλους.

συμπέρασμα

Το νέο MaterialDatePicker έχει κάποια εξαιρετική λειτουργικότητα που πιθανότατα θα καλύψει τις περισσότερες περιπτώσεις χρήσης της ημερομηνίας.

Ωστόσο, το καλύτερο μέρος του σε κάτι σαν το AppCompat CalendarView είναι ότι είναι χτισμένο με έναν σύνθετο τρόπο. Επομένως, μπορεί εύκολα να επεκταθεί και να τροποποιηθεί για συγκεκριμένες περιπτώσεις χρήσης, ενώ θα ήταν πολύ πιο δύσκολο να επιτευχθούν τέτοια πράγματα στο CalendarView.

Ιδιαίτερα ευχαριστώ

Θα ήθελα να επισημάνω ορισμένα άτομα που βοήθησαν την ομότιμη κριτική αυτού του άρθρου:

Μοιράσου Το Με Τους Φίλους Σου: