昨天介紹了完小條的 UI,將整個 NowPlaying 向上拉起後,還有一整個大頁面可以完整顯示播放器的頁面,今天就來實作這個功能(滿版 UI),顯示的內容包含小條 UI 的內容,有多顯示目前播放時間和總播放時間,還有上下一首的功能。
原本昨天介紹的小條 UI 提取到 section_now_playing_small,今天要新加的 UI 就寫到 section_now_playing_large,這邊是使用 merge 和 include的方式,細節可以參考:Android抽象佈局——include、merge 、ViewStub,使用 merge 可以減少 view hierarchy。
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/bottomSheetNowPlayingFragmentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
app:behavior_peekHeight="70dp"
app:layout_behavior="@string/bottom_sheet_behavior">
<include layout="@layout/section_now_playing_small" />
<include layout="@layout/section_now_playing_large" />
</androidx.constraintlayout.widget.ConstraintLayout>
在 large 的 UI 沒有特別的設定,和之前差不多,就不特別介紹了。都使用 ConstraintLayout 來畫 UI,在畫上一首、播放和下一首時特別方便,互相參考後就能平均分配在空間上了。
<ImageButton
android:id="@+id/largePreviousButton"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginTop="20dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_skip_previous"
app:layout_constraintEnd_toStartOf="@id/largePlayPauseButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/nowDuration" />
<ImageButton
android:id="@+id/largePlayPauseButton"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginTop="20dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/asl_playpause"
app:layout_constraintEnd_toStartOf="@id/largeNextButton"
app:layout_constraintStart_toEndOf="@id/largePreviousButton"
app:layout_constraintTop_toBottomOf="@id/nowDuration" />
<ImageButton
android:id="@+id/largeNextButton"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginTop="20dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="0dp"
android:src="@drawable/ic_skip_next"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/largePlayPauseButton"
app:layout_constraintTop_toBottomOf="@id/nowDuration" />
再來是滑開 NowPlaying 頁面時,要讓小條的 UI 慢慢消失,因為和滿版 UI 同時存在會有點奇怪 XD
bottomSheetBehavior.addBottomSheetCallback(object :
BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
Log.d(TAG, "slideOffset:$slideOffset")
sectionNowPlayingSmall.alpha = 1 - slideOffset
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
when (newState) {
BottomSheetBehavior.STATE_COLLAPSED -> Log.d(TAG, "STATE_COLLAPSED")
BottomSheetBehavior.STATE_DRAGGING -> {
Log.d(TAG, "STATE_DRAGGING")
sectionNowPlayingSmall.visibility = View.VISIBLE
}
BottomSheetBehavior.STATE_EXPANDED -> {
Log.d(TAG, "STATE_EXPANDED")
sectionNowPlayingSmall.visibility = View.GONE
}
BottomSheetBehavior.STATE_HIDDEN -> Log.d(TAG, "STATE_HIDDEN")
BottomSheetBehavior.STATE_HALF_EXPANDED -> Log.d(TAG, "STATE_HALF_EXPANDED")
BottomSheetBehavior.STATE_SETTLING -> Log.d(TAG, "STATE_SETTLING")
}
}
})
使用 alpha 來控制透明度,因為 slideOffset 在頁面滑到頂時是 1,而 alpha 值在 0 時是透明的,1 是正常顯示,這邊就用線性的轉換,隨著向上滑動,小條的 UI 越來越淡。在滑到頂時會互叫 STATE_EXPANDED,這時候就將 layout 設定成 GONE,使用者就不能點擊到,在滑動時再讓元件可見。
效果圖:
程式碼在這,分支名稱(day18_now_playing_large_ui): Fancy/day18_now_playing_large_ui