Sprout의 엔지니어링: Android 월 선택기 구축
게시 됨: 2020-06-26참고: 이 기사는 2020년 6월 1일 현재 Material Components 버전 1.2.0-beta01 을 기반으로 작성되었습니다.
Sprout Social의 소규모 Android 팀에서 3년 반 동안 일하면서 제가 매일 일하도록 동기를 부여하는 주요 요소 중 하나는 우리가 최선이라고 생각하는 방식으로 문제를 해결할 수 있는 회사의 자유와 신뢰입니다.
제품 업데이트 제공 기간을 고려하면서 필요하다고 생각하는 문제에 대한 다양한 솔루션을 자유롭게 조사하고 탐색할 수 있으므로 고객과 소프트웨어 모두를 위한 최상의 솔루션을 찾을 수 있습니다.
그러한 과제 중 하나는 새로운 모바일 보고 기능을 위한 UI 구성요소를 구축하는 것과 관련되었습니다. 이 새로운 구성 요소는 사용자가 분석 보고서의 날짜 범위를 지정할 수 있는 월 선택기였습니다.
우리가 선택한 출발점은 기존 Material Components Library였습니다. 이 라이브러리는 처음부터 시작하지 않고 적극적으로 유지 관리되며 Material 사양과 일치합니다. 이 라이브러리를 기반으로 하면 스스로 작성해야 하는 논리의 양을 줄일 수 있습니다.
이 기사에서는 이 프로세스에 접근한 방법, Sprout Android 앱을 빌드하는 데 있어 몇 가지 고유한 요소, 그 과정에서 발생하고 수정된 몇 가지 "문제점", 비슷한 프로젝트를 진행 중입니다.
소개
Android Material Components 1.1.0 릴리스에는 새로운 날짜 선택기 UI 구성 요소가 도입되었습니다. AppCompat CalendarView
에 대한 이 새로운 MaterialDatePicker
의 환영 추가 사항 중 하나는 달력 보기 또는 텍스트 입력 필드를 사용하여 날짜 범위를 선택할 수 있는 기능입니다.
이전 AppCompat CalendarView는 그다지 유연하지 않았습니다. 해결해야 하는 제한된 사용 사례에 대한 좋은 구성 요소였습니다. 즉, 단일 날짜와 선택적 최소 및 최대 날짜를 선택하여 허용되는 날짜 범위 경계를 지정합니다.
새로운 MaterialDatePicker는 확장된 동작 기능을 사용할 수 있도록 보다 유연하게 구축되었습니다. 선택기의 동작을 조정하고 수정하기 위해 구현할 수 있는 일련의 인터페이스를 통해 작동합니다.
이 동작 수정은 MaterialDatePicker.Builder
클래스의 빌더 패턴 함수 세트를 통해 런타임에 수행됩니다.
이는 구성 가능한 인터페이스 구성 요소를 통해 이 MaterialDatePicker
의 기본 동작을 확장할 수 있음을 의미합니다.
참고: MaterialDatePicker
가 활용하는 다양한 구성 요소가 있지만 이 기사에서는 날짜 선택 구성 요소만 다룹니다.
기간 선택기
Sprout Social Android 팀은 분석 보고서 섹션을 구축하는 중이었습니다.
이 새로운 섹션을 통해 사용자는 보고서에서 다룰 일련의 필터와 날짜 범위를 선택할 수 있습니다.
MaterialDatePicker
는 사용 사례를 달성하기 위해 활용할 수 있는 사전 구축된 구성 요소와 함께 제공됩니다.
가장 일반적인 경우 사용자가 날짜 범위를 선택할 수 있도록 미리 빌드된 MaterialDatePicker
로 충분합니다.
이 코드 블록을 사용하면 사용자가 날짜 범위를 선택할 수 있는 날짜 선택기가 제공됩니다.
월간 날짜 선택기
날짜 선택이 더 독특한 Sprout Social 보고서 중 하나는 Twitter Trends 보고서입니다.
이 보고서는 모든 종류의 날짜 범위를 허용하는 대신 한 달 선택을 적용한다는 점에서 다른 보고서와 다릅니다.
웹 앱은 드롭다운 양식 필드를 사용하여 이를 처리합니다.
MaterialDatePicker
는 이전 섹션에서 논의한 사전 빌드된 Material Date Range Picker로 이러한 제한을 적용할 방법이 없습니다. 다행히 MaterialDatePicker는 특정 사용 사례에 대한 기본 동작을 확장할 수 있는 구성 가능한 부분으로 구축되었습니다.
날짜 선택 동작
MaterialDatePicker
는 선택기의 선택 논리에 사용되는 인터페이스로 DateSelector
를 활용합니다.
Javadoc에서:
"캘린더가 선택 항목을 표시하고 반환하는 방법을 제어하기 위한 {@link MaterialCalendar<S>}
사용자용 인터페이스..."
MaterialDatePicker.Builder.dateRangePicker()
는 위의 예에서 사용한 RangeDateSelector
의 빌더 인스턴스를 반환합니다.
이 클래스는 DateSelector
를 구현하는 미리 빌드된 선택기입니다.
월별 날짜 선택 행동에 대한 브레인스토밍
사용 사례의 경우 사용자가 선택한 날짜 범위로 한 달 전체를 선택하도록 하는 방법을 원했습니다. 예: 2020년 5월, 2020년 4월 등
위에서 참조한 미리 빌드된 RangeDateSelector
를 통해 대부분의 작업을 수행할 수 있다고 생각했습니다. 구성 요소를 통해 사용자는 날짜 범위를 선택하고 [하한, 상한] 경계 를 적용할 수 있습니다.
누락된 유일한 것은 한 달 전체를 자동 선택하도록 선택을 적용하는 방법이었습니다. RangeDateSelector
의 기본 동작은 사용자가 시작 날짜와 종료 날짜를 선택하도록 합니다.
사용자가 해당 월의 날짜를 선택하면 선택기가 날짜 범위로 전체 월을 자동으로 선택하는 동작을 원했습니다.
우리가 결정한 솔루션은 RangeDateSelector
를 확장한 다음 대신 전체 월을 자동 선택하도록 날짜 선택 동작을 재정의하는 것이었습니다.
운 좋게도 인터페이스 DateSelector
에서 재정의할 수 있는 함수가 있습니다. select(selection: Long)
입니다.
이 함수는 사용자가 선택기에서 날짜를 선택하면 호출되며 선택된 날짜는 epoch에서 UTC 밀리초 단위로 전달됩니다.
월별 날짜 선택 동작 구현
구현은 우리가 원하는 동작을 얻기 위해 재정의할 수 있는 명확한 함수가 있기 때문에 가장 간단한 부분으로 판명되었습니다.
기본 논리는 다음과 같습니다.
- 사용자가 날짜를 선택합니다.
-
select()
함수는 Epoch에서 Long UTC 밀리초 단위로 선택된 날짜와 함께 호출됩니다. - 우리에게 주어진 주어진 날로부터 그 달의 1일과 마지막 날을 구하십시오.
-
super.select(1st of month)
및super.select(last day of month)
매월 말일)에 전화 걸기 -
RangeDateSelector
의 상위 동작은 예상대로 작동해야 하며 날짜 범위로 월을 선택해야 합니다.
함께 모아서
이제 Custom MonthRangeDateSelector
가 있으므로 MaterialDatePicker
를 설정할 수 있습니다.
예를 들어 다음과 같이 선택 결과를 처리할 수 있습니다.
결과는 다음과 같습니다.
잡다한 것들
이 솔루션에 도달하는 것을 어렵게 만든 한 가지 주요 문제가 있었습니다.
MonthRangeDateSelector
를 빌드하는 데 사용된 기본 구성 요소는 RangeDateSelector 클래스와 RangeDateSelector
인터페이스 DateSelector
. 이 문서에 사용된 라이브러리 버전(1.2.0-beta01)은 이 두 파일의 가시성을 제한하여 확장 또는 구현을 방해했습니다.
결과적으로 새로운 MonthRangeDateSelector
를 성공적으로 컴파일할 수 있었지만 컴파일러는 그렇게 하지 못하도록 하는 매우 무서운 경고를 표시했습니다.
이 컴파일러 경고를 숨기는 한 가지 방법은 다음과 같이 @Suppress("RestrictedApi")
를 추가하는 것입니다.
이 경험은 Material Components Library가 Android 개발자 커뮤니티에 몇 가지 훌륭한 새 구성 요소를 제공했음에도 불구하고 여전히 진행 중인 작업을 보여줍니다.
이 라이브러리의 가장 큰 부분은 Android 커뮤니티의 피드백에 대한 개방성입니다! 이 컴포넌트 가시성 제한을 발견한 후 저는 Github 프로젝트에서 이슈를 열었고 심지어 즉시 해결하기 위해 PR을 열었습니다.
Material Components 팀과 Android 커뮤니티 간의 이 공개 피드백 루프는 모두를 위한 훌륭한 협업과 결과를 낳습니다.
결론
새로운 MaterialDatePicker
에는 날짜 선택의 대부분의 사용 사례를 다룰 수 있는 뛰어난 기본 기능이 있습니다.
그러나 AppCompat CalendarView와 같은 것보다 가장 좋은 점은 구성 가능한 방식으로 빌드된다는 것입니다. 따라서 특정 사용 사례에 대해 쉽게 확장 및 수정할 수 있지만 CalendarView
에서 이러한 작업을 수행하는 것은 훨씬 더 어렵습니다.
특별한 감사
이 기사를 동료 검토하는 데 도움이 된 몇 가지 사람들을 강조하고 싶습니다.
- 닉 루트(Github)
- 마이크 울프슨(Github)
- 라이언 필립스(LinkedIn)
- Lucas Moellers(Github)
- 미트 파텔(LinkedIn)