完成播歌功能的部分,再來整幾天會和 UI 比較相關,來實作播放的介面,播歌介面除了之前有實作的 Notification,這個比較偏向是系統的元件,把必要的資訊傳入,系統就會產生 notifcation,並且在鎖屏畫面時,也會顯示。那在 App 裡面,也想要做一個播放介面來控制播放,知道現在歌曲的相關資訊,並且可以控制歌曲(上、下一首、播放進度.....等行為),就需要自己來實作頁面了。
今天開始就來實作介面,從前一天的介紹(MediaController 實作),可以取得播放的相關資訊,有這些資訊就可以拿來顯示了。
UI 的介面設計使用 Bottom Sheet 元件 來實作播放中頁面:
Ref: https://material.io/components/sheets-bottom#usage
可以看到紫色這塊就是播放中的頁面,上面就是原本頁面的內容,在播放的情況下使用者還可以繼續瀏覽,但如果使用者想要看播放中更詳細的資訊,就可以向上滑動紫色的這塊,播放中的頁面就會佔滿整個畫面,就如同 Youtube、Spotify、KKBOX 的播放中頁面的行為。
我們先來建立一個空的頁面,就叫做 NowPlayingFragment,在 uamp 專案裡面也有類似的設計,只是設計成一般頁面,為整頁播放的樣式。
class NowPlayingFragment : Fragment() {
private lateinit var bottomSheetBehavior: BottomSheetBehavior<ConstraintLayout>
......
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setBottomSheetBehavior()
}
private fun setBottomSheetBehavior() {
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetNowPlayingFragmentLayout)
bottomSheetBehavior.isHideable = false
bottomSheetBehavior.addBottomSheetCallback(object :
BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
Log.d(TAG, "slideOffset:$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")
BottomSheetBehavior.STATE_EXPANDED -> Log.d(TAG, "STATE_EXPANDED")
BottomSheetBehavior.STATE_HIDDEN -> Log.d(TAG, "STATE_HIDDEN")
BottomSheetBehavior.STATE_SETTLING -> Log.d(TAG, "STATE_SETTLING")
}
}
})
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<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">
......
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
在頁面中加入 BottomSheetBehavior,並在程式碼設定有滑動行為的元件(定義在 layout 內)
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetNowPlayingFragmentLayout)
並搭配上面的程式碼,需要設定 layout_behavior,並指定初始高度為 70 dp。
app:behavior_peekHeight="70dp"
app:layout_behavior="@string/bottom_sheet_behavior"
呈現的效果為:
在 NowPlaying 的頁面分成兩部份,一個是剛點開呈現的小條 UI,一個是展開後的整個蓋板的 UI,會分別在之後的天數實作。
程式碼在這,分支名稱(day15_nowplaying_ui): Fancy/day15_nowplaying_ui