feat: Now Playing screen MVP (nb. layout xml and Compose UI are two different sources)

This commit is contained in:
2026-05-14 00:44:43 +02:00
parent 395609791f
commit 26115f773f
23 changed files with 885 additions and 1 deletions

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorOnSurface"
android:pathData="M6,19h4V5H6V19zM14,19h4V5h-4V19z" />
</vector>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorOnSurface"
android:pathData="M8,5v14l11,-7L8,5z" />
</vector>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorOnSurface"
android:pathData="M6,18l8.5,-6L6,6V18zM16,6h2v12h-2V6z" />
</vector>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorOnSurface"
android:pathData="M6,6h2v12H6V6zM9.5,12l8.5,6V6L9.5,12z" />
</vector>

View File

@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Now Playing — View hierarchy for Android Studio Layout Editor / Design preview.
The launcher still uses Compose (see MainActivity); wire this layout when adding a View-based screen.
-->
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:paddingStart="@dimen/now_playing_horizontal_padding"
android:paddingTop="@dimen/now_playing_vertical_padding"
android:paddingEnd="@dimen/now_playing_horizontal_padding"
android:paddingBottom="@dimen/now_playing_vertical_padding"
tools:theme="@style/Theme.LockstepPlayer">
<TextView
android:id="@+id/text_track_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Example Track Title" />
<TextView
android:id="@+id/text_track_artist"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_track_title"
tools:text="Example Artist" />
<com.google.android.material.slider.Slider
android:id="@+id/slider_progress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:stepSize="0.01"
android:value="0.35"
android:valueFrom="0"
android:valueTo="1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_track_artist" />
<TextView
android:id="@+id/text_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textAppearance="?attr/textAppearanceLabelMedium"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/slider_progress"
tools:text="1:15" />
<TextView
android:id="@+id/text_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textAppearance="?attr/textAppearanceLabelMedium"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/slider_progress"
tools:text="3:35" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_after_times"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="text_position,text_duration" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/button_play_pause"
android:layout_width="@dimen/now_playing_play_button_size"
android:layout_height="@dimen/now_playing_play_button_size"
android:layout_marginTop="12dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/cd_play_pause"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintEnd_toStartOf="@id/button_next"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toEndOf="@id/button_previous"
app:layout_constraintTop_toBottomOf="@id/barrier_after_times"
app:srcCompat="@drawable/ic_play_arrow_24" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/button_previous"
android:layout_width="@dimen/now_playing_transport_button_size"
android:layout_height="@dimen/now_playing_transport_button_size"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/cd_previous_track"
android:padding="14dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@id/button_play_pause"
app:layout_constraintEnd_toStartOf="@id/button_play_pause"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/button_play_pause"
app:srcCompat="@drawable/ic_skip_previous_24" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/button_next"
android:layout_width="@dimen/now_playing_transport_button_size"
android:layout_height="@dimen/now_playing_transport_button_size"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/cd_next_track"
android:padding="14dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@id/button_play_pause"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/button_play_pause"
app:layout_constraintTop_toTopOf="@id/button_play_pause"
app:srcCompat="@drawable/ic_skip_next_24" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="now_playing_horizontal_padding">24dp</dimen>
<dimen name="now_playing_vertical_padding">16dp</dimen>
<dimen name="now_playing_transport_button_size">80dp</dimen>
<dimen name="now_playing_play_button_size">104dp</dimen>
</resources>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Lockstep</string>
<string name="cd_previous_track">Previous track</string>
<string name="cd_play_pause">Play or pause</string>
<string name="cd_next_track">Next track</string>
</resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.LockstepPlayer" parent="Theme.Material3.DayNight.NoActionBar" />
</resources>