Sprout'ta Mühendislik: Bir Android ay seçici oluşturma
Yayınlanan: 2020-06-26Not: Bu makale, 1 Haziran 2020 itibariyle Malzeme Bileşenleri 1.2.0-beta01 sürümüne dayanmaktadır.
Sprout Social'da küçük bir Android ekibinde çalıştığım üç buçuk yıl boyunca, beni her gün işe gelmem için motive eden en önemli şeylerden biri, şirketimizin bir sorunu en iyi gördüğümüz şekilde ele alma özgürlüğü ve güvenidir.
Gerekli gördüğümüz bir soruna yönelik birçok farklı çözümü araştırma ve keşfetme özgürlüğü ve aynı zamanda ürün güncellemelerini teslim etmek için bir zaman çerçevesini hesaba katma özgürlüğü, hem müşterilerimiz hem de yazılımımız için en iyi çözümü bulmamızı sağlar.
Bu tür zorluklardan biri, yeni Mobil Raporlama özelliğimiz için bir UI bileşeni oluşturmayı içeriyordu. Bu yeni bileşen, kullanıcılarımızın bir analiz raporu için bir tarih aralığı kapsamasına olanak tanıyan bir ay seçiciydi.
Seçtiğimiz başlangıç yeri mevcut Malzeme Bileşenleri Kitaplığıydı. Sıfırdan başlamak yerine, bu kitaplık aktif olarak korunur ve Malzeme özellikleriyle uyumludur. Temel olarak bu kitaplık ile kendimiz yazmamız gereken mantık miktarını azaltabiliriz.
Bu makalede, bu sürece nasıl yaklaştığımızı, Sprout Android uygulamasını oluştururken bazı benzersiz faktörleri, bu süreçte ortaya çıkan (ve düzeltilen) birkaç "sapıklığı" ve benzer bir proje üzerinde çalışıyor.
giriiş
Android Malzeme Bileşenleri 1.1.0 Sürümü, yeni bir Tarih Seçici Kullanıcı Arayüzü Bileşenini tanıttı. Bu yeni MaterialDatePicker
AppCompat CalendarView
üzerindeki hoş geldiniz eklemelerinden biri, bir Takvim Görünümü veya bir Metin Giriş Alanı kullanarak bir tarih aralığı seçme yeteneğidir.
Eski AppCompat CalendarView çok esnek değildi. Çözmesi amaçlanan sınırlı kullanım durumu için iyi bir bileşendi; yani, izin verilen bir tarih aralığı sınırı belirtmek için tek bir tarih ve isteğe bağlı minimum ve maksimum tarihler seçmek.
Yeni MaterialDatePicker, genişletilmiş davranış işlevselliğinin kullanımına izin vermek için daha fazla esneklikle oluşturuldu. Seçicinin davranışını değiştirmek ve değiştirmek için uygulanabilecek bir dizi arabirim aracılığıyla çalışır.
Bu davranış değişikliği, çalışma zamanında MaterialDatePicker.Builder
sınıfındaki bir dizi oluşturucu desen işlevi aracılığıyla yapılır.
Bu, bu MaterialDatePicker
temel davranışını birleştirilebilir arabirim bileşenleri aracılığıyla genişletebileceğimiz anlamına gelir.
Not: MaterialDatePicker
kullandığı birkaç farklı bileşen olsa da, bu makalede yalnızca Tarih Seçim Bileşenini ele alacağız.
Tarih aralığı seçici
Sprout Social Android ekibi, Analitik Raporlar Bölümümüzü oluşturma sürecindeydi.
Bu yeni bölüm, kullanıcılarımızın raporun kapsayacağı bir dizi filtre ve bir dizi tarih aralığı seçmesine olanak tanır.
MaterialDatePicker
, kullanım senaryomuzu gerçekleştirmek için yararlanabileceğimiz bazı önceden oluşturulmuş bileşenlerle birlikte geldi.
Bir kullanıcının bir tarih aralığı seçmesine izin veren en yaygın durumumuz için önceden oluşturulmuş MaterialDatePicker
yeterli olacaktır:
Bu kod bloğuyla, kullanıcıların bir tarih aralığı seçmesine olanak tanıyan bir Tarih Seçici elde ederiz.
Aylık tarih seçici
Daha özgün tarih seçimine sahip Sprout Social raporlarından biri de Twitter Trends Report.
Bu raporun diğerlerinden farkı, herhangi bir tarih aralığına izin vermek yerine tek bir aylık seçimi zorunlu kılmasıdır, yani bir kullanıcı yalnızca Mart 2020'yi 3 Mart ile 16 Mart 2020 arasında seçebilir.
Web uygulamamız bunu bir açılır form alanı kullanarak halleder:
MaterialDatePicker
, önceki bölümde tartışılan önceden oluşturulmuş Malzeme Tarih Aralığı Seçici ile böyle bir kısıtlamayı uygulamak için bir yola sahip değildir. Neyse ki MaterialDatePicker, belirli kullanım durumumuz için varsayılan davranışı genişletmemize izin veren şekillendirilebilir parçalarla oluşturuldu.
Tarih seçimi davranışı
MaterialDatePicker
, seçicinin seçim mantığı için kullanılan arabirim olarak bir DateSelector
yararlanır.
Javadoc'tan:
“Takvimin seçimleri nasıl görüntülediğini ve döndürdüğünü kontrol etmek için {@link MaterialCalendar<S>}
kullanıcıları için arayüz…”
MaterialDatePicker.Builder.dateRangePicker()
öğesinin, yukarıdaki örnekte kullandığımız RangeDateSelector
oluşturucu örneğini döndürdüğünü fark edeceksiniz.
Bu sınıf, DateSelector
uygulayan önceden oluşturulmuş bir seçicidir.
Aylık bir tarih seçimi davranışı için beyin fırtınası
Kullanım durumumuz için, kullanıcılarımızın seçili bir tarih aralığı olarak tam bir ayı seçmesini sağlayacak bir yol istedik; örneğin Mayıs 2020, Nisan 2020 vb.
Yukarıda atıfta bulunulan önceden RangeDateSelector
bizi oraya kadar götürdüğünü düşündük. Bileşen, kullanıcının bir tarih aralığı seçmesine ve bir [alt, üst] sınır uygulamasına izin verdi.
Eksik olan tek şey, tüm ayı otomatik olarak seçmek için bir seçimi zorlamanın bir yoluydu. RangeDateSelector
varsayılan davranışı, kullanıcının bir başlangıç tarihi ve bir bitiş tarihi seçmesini sağlar.
Bir kullanıcı ayda bir gün seçtiğinde, seçicinin tüm ayı tarih aralığı olarak otomatik olarak seçeceği bir davranış istedik.
Karar verdiğimiz çözüm, RangeDateSelector
genişletmek ve ardından tüm ayı otomatik olarak seçmek için gün seçim davranışını geçersiz kılmaktı.
Neyse ki, DateSelector
arayüzünden geçersiz kılabileceğimiz bir fonksiyon var: select(selection: Long)
.
Bu işlev, bir kullanıcı seçicide bir gün seçtiğinde, seçilen gün epoch'tan UTC milisaniye cinsinden geçtiğinde çağrılır.
Aylık bir tarih seçme davranışı uygulama
Uygulamanın en basit kısmı olduğu ortaya çıktı, çünkü istediğimiz davranışı elde etmek için geçersiz kılabileceğimiz net bir fonksiyonumuz var.
Temel mantık şu olacak:
- Kullanıcı bir gün seçer.
-
select()
işlevi, çağdan itibaren Uzun UTC milisaniye cinsinden seçilen günle birlikte çağrılır. - Bize geçen verilen günden ayın ilk ve son gününü bulun.
-
super.select(1st of month)
vesuper.select(last day of month)
için arama yapın -
RangeDateSelector
üst davranışı beklendiği gibi çalışmalı ve tarih aralığı olarak ayı seçmelidir.
Hepsini bir araya koy
Artık Custom MonthRangeDateSelector
sahip olduğumuza göre MaterialDatePicker
kurabiliriz.
Örneği daha ileri götürmek için, seçimin sonucunu şu şekilde işleyebiliriz:
Sonuç şöyle görünecek:
yakalandım
Bu çözüme ulaşmayı zorlaştıran tek bir önemli sorun vardı.
MonthRangeDateSelector'ımızı oluşturmak için kullanılan birincil bileşenler, MonthRangeDateSelector
sınıfı ve RangeDateSelector
DateSelector
. Bu makalede kullanılan kitaplığın sürümü (1.2.0-beta01), genişletmeyi veya uygulamayı caydırmak için bu iki dosyanın görünürlüğünü kısıtladı.
Sonuç olarak, yeni MonthRangeDateSelector
başarıyla derleyebilmemize rağmen, derleyici bizi bunu yapmaktan caydırmak için çok korkutucu bir uyarı verdi:
Bu derleyici uyarısını gizlemenin bir yolu, şöyle bir @Suppress("RestrictedApi")
:
Bu deneyim, Material Components Library'nin Android Geliştirici Topluluğuna bazı harika yeni bileşenler sağlamasına rağmen, bunun nasıl hala devam eden bir çalışma olduğunu göstermektedir.
Bu kitaplığın büyük bir kısmı, Android Topluluğundan gelen geri bildirimlere açık olmasıdır! Bu bileşen görünürlük kısıtlamasını keşfettikten sonra Github Projesi'nde bir konu açtım ve hatta hemen ele almak için bir PR açtım.
Material Components Team ve Android Community arasındaki bu açık geri bildirim döngüsü, herkes için harika bir işbirliği ve sonuçlar doğuruyor.
Çözüm
Yeni MaterialDatePicker
, tarih seçimiyle ilgili çoğu kullanım örneğini kapsayabilecek, kullanıma hazır bazı harika işlevlere sahiptir.
Bununla birlikte, AppCompat CalendarView gibi bir şeye göre en iyi yanı, birleştirilebilir bir şekilde oluşturulmuş olmasıdır. Bu nedenle, belirli kullanım durumları için kolayca genişletilebilir ve değiştirilebilir, ancak bu tür şeyleri CalendarView
gerçekleştirmek çok daha zor olacaktır.
Özel teşekkür
Bu makalenin hakem tarafından gözden geçirilmesine yardımcı olan bazı kişilerin altını çizmek istiyorum:
- Nick Rout (Github)
- Mike Wolfson (Github)
- Ryan Phillips (LinkedIn)
- Lucas Moellers (Github)
- Mit Patel (LinkedIn)