Added support for landscape mode.

This commit is contained in:
Antoine POPINEAU 2019-11-05 21:23:29 +01:00
parent cac32332e0
commit 0cb4bda212
No known key found for this signature in database
GPG Key ID: A78AC64694F84063
13 changed files with 809 additions and 71 deletions

View File

@ -13,7 +13,6 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:screenOrientation="portrait"
android:supportsRtl="true"
android:theme="@style/AppTheme">
@ -35,6 +34,7 @@
<activity
android:name="com.github.apognu.otter.activities.LoginActivity"
android:configChanges="screenSize|orientation"
android:launchMode="singleInstance" />
<activity android:name="com.github.apognu.otter.activities.MainActivity" />
<activity

View File

@ -5,19 +5,21 @@ import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Intent
import android.content.res.Configuration
import android.graphics.Bitmap
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.util.DisplayMetrics
import android.view.*
import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.SeekBar
import androidx.appcompat.app.AppCompatActivity
import androidx.core.graphics.drawable.toDrawable
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.github.apognu.otter.R
import com.github.apognu.otter.fragments.BrowseFragment
import com.github.apognu.otter.fragments.LandscapeQueueFragment
import com.github.apognu.otter.fragments.QueueFragment
import com.github.apognu.otter.playback.MediaControlsManager
import com.github.apognu.otter.playback.PlayerService
@ -34,6 +36,7 @@ import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class MainActivity : AppCompatActivity() {
enum class ResultCode(val code: Int) {
@ -101,6 +104,10 @@ class MainActivity : AppCompatActivity() {
}
}
})
landscape_queue?.let {
supportFragmentManager.beginTransaction().replace(R.id.landscape_queue, LandscapeQueueFragment()).commit()
}
}
override fun onBackPressed() {
@ -155,6 +162,10 @@ class MainActivity : AppCompatActivity() {
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
}
private fun launchFragment(fragment: Fragment) {
supportFragmentManager.fragments.lastOrNull()?.also { oldFragment ->
oldFragment.enterTransition = null
@ -206,6 +217,12 @@ class MainActivity : AppCompatActivity() {
it.bottomMargin = it.bottomMargin / 2
}
landscape_queue?.let { landscape_queue ->
(landscape_queue.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
it.bottomMargin = it.bottomMargin / 2
}
}
now_playing.animate()
.alpha(0.0f)
.setDuration(400)
@ -233,6 +250,12 @@ class MainActivity : AppCompatActivity() {
(container.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
it.bottomMargin = it.bottomMargin * 2
}
landscape_queue?.let { landscape_queue ->
(landscape_queue.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
it.bottomMargin = it.bottomMargin * 2
}
}
}
now_playing_title.text = track.title
@ -251,33 +274,60 @@ class MainActivity : AppCompatActivity() {
.centerCrop()
.into(now_playing_cover)
Picasso.get()
.maybeLoad(maybeNormalizeUrl(track.album.cover.original))
.fit()
.centerCrop()
.into(now_playing_details_cover)
now_playing_details_cover?.let { now_playing_details_cover ->
Picasso.get()
.maybeLoad(maybeNormalizeUrl(track.album.cover.original))
.fit()
.centerCrop()
.into(now_playing_details_cover)
}
favoriteCheckRepository.fetch().untilNetwork(IO) { favorites, _, _ ->
GlobalScope.launch(Main) {
track.favorite = favorites.contains(track.id)
if (now_playing_details_cover == null) {
GlobalScope.launch(IO) {
val width = DisplayMetrics().apply {
windowManager.defaultDisplay.getMetrics(this)
}.widthPixels
when (track.favorite) {
true -> now_playing_details_favorite.setColorFilter(getColor(R.color.colorFavorite))
false -> now_playing_details_favorite.setColorFilter(getColor(R.color.controlForeground))
val backgroundCover = Picasso.get()
.maybeLoad(maybeNormalizeUrl(track.album.cover.original))
.get()
.run { Bitmap.createScaledBitmap(this, width, width, false).toDrawable(resources) }
.apply {
alpha = 20
gravity = Gravity.CENTER
}
withContext(Main) {
now_playing_details.background = backgroundCover
}
}
}
now_playing_details_favorite.setOnClickListener {
when (track.favorite) {
true -> {
favoriteRepository.deleteFavorite(track.id)
now_playing_details_favorite.setColorFilter(getColor(R.color.controlForeground))
}
now_playing_details_favorite?.let { now_playing_details_favorite ->
favoriteCheckRepository.fetch().untilNetwork(IO) { favorites, _, _ ->
GlobalScope.launch(Main) {
track.favorite = favorites.contains(track.id)
false -> {
favoriteRepository.addFavorite(track.id)
now_playing_details_favorite.setColorFilter(getColor(R.color.colorFavorite))
when (track.favorite) {
true -> now_playing_details_favorite.setColorFilter(getColor(R.color.colorFavorite))
false -> now_playing_details_favorite.setColorFilter(getColor(R.color.controlForeground))
}
}
}
}
now_playing_details_favorite?.let { now_playing_details_favorite ->
now_playing_details_favorite.setOnClickListener {
when (track.favorite) {
true -> {
favoriteRepository.deleteFavorite(track.id)
now_playing_details_favorite.setColorFilter(getColor(R.color.controlForeground))
}
false -> {
favoriteRepository.addFavorite(track.id)
now_playing_details_favorite.setColorFilter(getColor(R.color.colorFavorite))
}
}
}

View File

@ -1,8 +1,12 @@
package com.github.apognu.otter.fragments
import android.graphics.Bitmap
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.Gravity
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.core.graphics.drawable.toDrawable
import androidx.core.os.bundleOf
import androidx.recyclerview.widget.RecyclerView
import androidx.transition.Fade
@ -14,6 +18,12 @@ import com.github.apognu.otter.repositories.AlbumsRepository
import com.github.apognu.otter.utils.*
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.fragment_albums.*
import kotlinx.android.synthetic.main.partial_now_playing.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.math.min
class AlbumsFragment : FunkwhaleFragment<Album, AlbumsAdapter>() {
override val viewRes = R.layout.fragment_albums
@ -51,12 +61,38 @@ class AlbumsFragment : FunkwhaleFragment<Album, AlbumsAdapter>() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Picasso.get()
.maybeLoad(maybeNormalizeUrl(artistArt))
.noFade()
.fit()
.centerCrop()
.into(cover)
cover?.let { cover ->
Picasso.get()
.maybeLoad(maybeNormalizeUrl(artistArt))
.noFade()
.fit()
.centerCrop()
.into(cover)
}
cover_background?.let {
activity?.let { activity ->
GlobalScope.launch(Dispatchers.IO) {
val width = DisplayMetrics().apply {
activity.windowManager.defaultDisplay.getMetrics(this)
}.widthPixels
val backgroundCover = Picasso.get()
.maybeLoad(maybeNormalizeUrl(artistArt))
.get()
.run { Bitmap.createScaledBitmap(this, width, width, false) }
.run { Bitmap.createBitmap(this, 0, 0, width, cover_background.height).toDrawable(resources) }
.apply {
alpha = 20
gravity = Gravity.CENTER
}
withContext(Dispatchers.Main) {
cover_background.background = backgroundCover
}
}
}
}
artist.text = artistName
}

View File

@ -0,0 +1,75 @@
package com.github.apognu.otter.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.apognu.otter.R
import com.github.apognu.otter.adapters.TracksAdapter
import com.github.apognu.otter.utils.*
import kotlinx.android.synthetic.main.partial_queue.*
import kotlinx.android.synthetic.main.partial_queue.view.*
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
class LandscapeQueueFragment : Fragment() {
private var adapter: TracksAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
watchEventBus()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.partial_queue, container, false).apply {
adapter = TracksAdapter(context, fromQueue = true).also {
queue.layoutManager = LinearLayoutManager(context)
queue.adapter = it
}
}
}
override fun onResume() {
super.onResume()
queue?.visibility = View.GONE
placeholder?.visibility = View.VISIBLE
refresh()
}
private fun refresh() {
GlobalScope.launch(Main) {
RequestBus.send(Request.GetQueue).wait<Response.Queue>()?.let { response ->
adapter?.let {
it.data = response.queue.toMutableList()
it.notifyDataSetChanged()
if (it.data.isEmpty()) {
queue?.visibility = View.GONE
placeholder?.visibility = View.VISIBLE
} else {
queue?.visibility = View.VISIBLE
placeholder?.visibility = View.GONE
}
}
}
}
}
private fun watchEventBus() {
GlobalScope.launch(Main) {
EventBus.get().collect { message ->
when (message) {
is Event.TrackPlayed -> refresh()
is Event.QueueChanged -> refresh()
}
}
}
}
}

View File

@ -15,6 +15,8 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.fragment_queue.*
import kotlinx.android.synthetic.main.fragment_queue.view.*
import kotlinx.android.synthetic.main.partial_queue.*
import kotlinx.android.synthetic.main.partial_queue.view.*
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.collect
@ -50,6 +52,10 @@ class QueueFragment : BottomSheetDialogFragment() {
adapter = TracksAdapter(context, FavoriteListener(), fromQueue = true).also {
queue.layoutManager = LinearLayoutManager(context)
queue.adapter = it
adapter = TracksAdapter(context, fromQueue = true).also {
included.queue.layoutManager = LinearLayoutManager(context)
included.queue.adapter = it
}
}
}
}
@ -57,7 +63,7 @@ class QueueFragment : BottomSheetDialogFragment() {
override fun onResume() {
super.onResume()
queue?.visibility = View.GONE
included.queue?.visibility = View.GONE
placeholder?.visibility = View.VISIBLE
refresh()
@ -66,16 +72,18 @@ class QueueFragment : BottomSheetDialogFragment() {
private fun refresh() {
GlobalScope.launch(Main) {
RequestBus.send(Request.GetQueue).wait<Response.Queue>()?.let { response ->
adapter?.let {
it.data = response.queue.toMutableList()
it.notifyDataSetChanged()
included?.let {
adapter?.let {
it.data = response.queue.toMutableList()
it.notifyDataSetChanged()
if (it.data.isEmpty()) {
queue?.visibility = View.GONE
placeholder?.visibility = View.VISIBLE
} else {
queue?.visibility = View.VISIBLE
placeholder?.visibility = View.GONE
if (it.data.isEmpty()) {
included.queue?.visibility = View.GONE
placeholder?.visibility = View.VISIBLE
} else {
included.queue?.visibility = View.VISIBLE
placeholder?.visibility = View.GONE
}
}
}
}

View File

@ -25,8 +25,6 @@ object AppContext {
fun init(context: Activity) {
setupNotificationChannels(context)
context.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
// CastContext.getSharedInstance(context)
FuelManager.instance.addResponseInterceptor { next ->

View File

@ -0,0 +1,61 @@
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal">
<FrameLayout
android:id="@+id/container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginBottom="?attr/actionBarSize"
android:layout_weight="1"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<FrameLayout
android:id="@+id/landscape_queue"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginBottom="?attr/actionBarSize"
android:layout_weight="1"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</LinearLayout>
<com.github.apognu.otter.views.NowPlayingView
android:id="@+id/now_playing"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
android:layout_margin="8dp"
android:alpha="0"
android:visibility="gone"
app:cardCornerRadius="8dp"
app:cardElevation="12dp"
app:layout_dodgeInsetEdges="bottom"
tools:alpha="1"
tools:visibility="visible">
<include layout="@layout/partial_now_playing" />
</com.github.apognu.otter.views.NowPlayingView>
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:theme="@style/AppTheme.AppBar"
app:backgroundTint="@color/colorPrimary"
app:layout_insetEdge="bottom"
app:navigationIcon="@drawable/ottericon"
tools:menu="@menu/toolbar" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout 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:id="@+id/swiper"
style="@style/AppTheme.Fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
android:clipChildren="false"
android:clipToPadding="false">
<androidx.core.widget.NestedScrollView
android:id="@+id/scroller"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurface"
android:elevation="1dp">
<LinearLayout
android:id="@+id/cover_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/albums"
android:textAllCaps="true"
android:textSize="14sp" />
<TextView
android:id="@+id/artist"
style="@style/AppTheme.Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
tools:text="Muse" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/albums"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
tools:itemCount="10"
tools:listitem="@layout/row_album" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@ -0,0 +1,209 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout 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:id="@+id/swiper"
style="@style/AppTheme.Fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionGroup="true">
<androidx.core.widget.NestedScrollView
android:id="@+id/scroller"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurface"
android:elevation="1dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/cover"
android:layout_width="match_parent"
android:layout_height="100dp"
android:contentDescription="@string/alt_album_cover"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0"
tools:src="@tools:sample/avatars"
tools:visibility="invisible" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/covers"
android:layout_width="match_parent"
android:layout_height="250dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0"
tools:visibility="visible">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent=".50" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent=".50" />
<com.github.apognu.otter.views.SquareImageView
android:id="@+id/cover_top_left"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
android:src="@drawable/cover"
app:layout_constraintBottom_toBottomOf="@id/vertical"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="@id/horizontal"
app:layout_constraintTop_toTopOf="parent"
tools:src="@tools:sample/avatars" />
<com.github.apognu.otter.views.SquareImageView
android:id="@+id/cover_top_right"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
android:src="@drawable/cover"
app:layout_constraintBottom_toBottomOf="@id/vertical"
app:layout_constraintLeft_toLeftOf="@id/horizontal"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@tools:sample/avatars" />
<com.github.apognu.otter.views.SquareImageView
android:id="@+id/cover_bottom_left"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
android:src="@drawable/cover"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="@id/horizontal"
app:layout_constraintTop_toTopOf="@id/vertical"
tools:src="@tools:sample/avatars" />
<com.github.apognu.otter.views.SquareImageView
android:id="@+id/cover_bottom_right"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
android:src="@drawable/cover"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@id/horizontal"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/vertical"
tools:src="@tools:sample/avatars" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/colorPrimary"
android:elevation="10dp"
android:text="@string/playback_shuffle"
android:textColor="@android:color/white"
app:icon="@drawable/play"
app:iconTint="@android:color/white"
app:layout_constraintBottom_toBottomOf="@id/cover"
app:layout_constraintLeft_toLeftOf="@id/cover"
app:layout_constraintRight_toRightOf="@id/cover"
app:layout_constraintTop_toBottomOf="@id/cover" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/artist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:textAllCaps="true"
android:textSize="14sp"
tools:text="Muse" />
<TextView
android:id="@+id/title"
style="@style/AppTheme.Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
tools:text="Absolution" />
</LinearLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/queue"
style="@style/AppTheme.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/playback_queue"
app:icon="@drawable/add" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/tracks"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:itemCount="10"
tools:listitem="@layout/row_track" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@ -0,0 +1,193 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="@+id/now_playing_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/summary"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:orientation="vertical">
<ProgressBar
android:id="@+id/now_playing_progress"
style="@android:style/Widget.Material.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-6dp"
android:layout_marginBottom="-6dp"
android:progress="40"
android:progressTint="@color/colorPrimary" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<FrameLayout
android:layout_width="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="16dp">
<com.github.apognu.otter.views.SquareImageView
android:id="@+id/now_playing_cover"
android:layout_width="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize"
tools:src="@tools:sample/avatars" />
<ProgressBar
android:id="@+id/now_playing_buffering"
android:layout_width="?attr/actionBarSize"
android:layout_height="?attr/actionBarSize"
android:indeterminate="true"
android:indeterminateTint="@color/controlForeground"
android:visibility="gone" />
</FrameLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:orientation="vertical">
<TextView
android:id="@+id/now_playing_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/itemTitle"
tools:text="Supermassive Black Hole" />
<TextView
android:id="@+id/now_playing_album"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Muse" />
</LinearLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/now_playing_toggle"
style="@style/AppTheme.OutlinedButton"
android:layout_width="?attr/actionBarSize"
android:layout_height="match_parent"
app:icon="@drawable/play" />
<ImageButton
android:id="@+id/now_playing_next"
style="@style/IconButton"
android:layout_width="?attr/actionBarSize"
android:layout_height="match_parent"
android:contentDescription="@string/control_next"
android:src="@drawable/next" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/now_playing_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/now_playing_details_controls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:orientation="vertical"
android:paddingTop="32dp">
<TextView
android:id="@+id/now_playing_details_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/itemTitle"
android:textSize="18sp"
tools:text="Supermassive Black Hole" />
<TextView
android:id="@+id/now_playing_details_artist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Muse" />
<SeekBar
android:id="@+id/now_playing_details_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:max="100"
android:progressBackgroundTint="#cacaca"
android:progressTint="@color/controlForeground"
android:thumbTint="@color/controlForeground" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/now_playing_details_progress_current"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="@+id/now_playing_details_progress_duration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textAlignment="textEnd" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginBottom="16dp"
android:gravity="center"
android:orientation="horizontal">
<ImageButton
android:id="@+id/now_playing_details_previous"
style="@style/IconButton"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginEnd="16dp"
android:contentDescription="@string/control_previous"
android:src="@drawable/previous" />
<com.google.android.material.button.MaterialButton
android:id="@+id/now_playing_details_toggle"
style="@style/AppTheme.OutlinedButton"
android:layout_width="64dp"
android:layout_height="64dp"
app:cornerRadius="64dp"
app:icon="@drawable/play"
app:iconSize="32dp" />
<ImageButton
android:id="@+id/now_playing_details_next"
style="@style/IconButton"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="16dp"
android:contentDescription="@string/control_next"
android:src="@drawable/next" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:layout_marginStart="16dp"
@ -14,33 +13,9 @@
app:cardCornerRadius="16dp"
app:cardElevation="4dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/queue"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:itemCount="10"
tools:listitem="@layout/row_track" />
<TextView
android:id="@+id/placeholder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="64dp"
android:layout_marginBottom="64dp"
android:drawableTop="@drawable/ottericon"
android:drawablePadding="16dp"
android:drawableTint="#525252"
android:text="@string/playback_queue_empty"
android:textAlignment="center"
android:visibility="gone"
tools:visibility="visible" />
</FrameLayout>
<include
android:id="@+id/included"
layout="@layout/partial_queue" />
</androidx.cardview.widget.CardView>

View File

@ -0,0 +1,29 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@layout/fragment_queue">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/queue"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:itemCount="10"
tools:listitem="@layout/row_track" />
<TextView
android:id="@+id/placeholder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="64dp"
android:layout_marginBottom="64dp"
android:drawableTop="@drawable/ottericon"
android:drawablePadding="16dp"
android:drawableTint="#525252"
android:text="@string/playback_queue_empty"
android:textAlignment="center"
android:visibility="gone"
tools:visibility="visible" />
</FrameLayout>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/cast"
android:iconTint="@android:color/white"
android:title="@string/toolbar_cast"
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
app:showAsAction="ifRoom" />
<item
android:id="@+id/nav_search"
android:icon="@drawable/search"
android:title="@string/toolbar_search"
app:showAsAction="ifRoom" />
<item
android:id="@+id/settings"
android:icon="@drawable/settings"
android:iconTint="@android:color/white"
android:title="@string/title_settings"
app:showAsAction="never" />
</menu>