all: misc changes
Miscellanious changes that accumulated over time.
This commit is contained in:
parent
170cdf80ef
commit
b42dfd0b53
14 changed files with 105 additions and 83 deletions
|
@ -27,6 +27,8 @@ at the cost of longer loading times
|
||||||
- Fixed default material theme being used before app shows up
|
- Fixed default material theme being used before app shows up
|
||||||
- Fixed shuffle shortcut and file opening not working on startup on some devices
|
- Fixed shuffle shortcut and file opening not working on startup on some devices
|
||||||
- Fixed issue where the notification position would not match if one seeked when paused
|
- Fixed issue where the notification position would not match if one seeked when paused
|
||||||
|
- Fixed issue where widget covers would not load
|
||||||
|
- Fixed issue where widget could not be sized to it's smallest form
|
||||||
|
|
||||||
#### What's Changed
|
#### What's Changed
|
||||||
- Play and skip icons are filled again
|
- Play and skip icons are filled again
|
||||||
|
|
|
@ -82,6 +82,8 @@ import java.util.Map;
|
||||||
* <p>To send useful accessibility events, set a title on bottom sheets that are windows or are
|
* <p>To send useful accessibility events, set a title on bottom sheets that are windows or are
|
||||||
* window-like. For BottomSheetDialog use {@link BottomSheetDialog#setTitle(int)}, and for
|
* window-like. For BottomSheetDialog use {@link BottomSheetDialog#setTitle(int)}, and for
|
||||||
* BottomSheetDialogFragment use {@link ViewCompat#setAccessibilityPaneTitle(View, CharSequence)}.
|
* BottomSheetDialogFragment use {@link ViewCompat#setAccessibilityPaneTitle(View, CharSequence)}.
|
||||||
|
*
|
||||||
|
* Modified at several points by OxygenCobalt to fix insane issues.
|
||||||
*/
|
*/
|
||||||
public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Behavior<V> {
|
public class NeoBottomSheetBehavior<V extends View> extends CoordinatorLayout.Behavior<V> {
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,21 @@ import org.oxycblt.auxio.ui.AuxioSheetBehavior
|
||||||
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||||
import org.oxycblt.auxio.util.systemGestureInsetsCompat
|
import org.oxycblt.auxio.util.systemGestureInsetsCompat
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The coordinator layout behavior used for the playback sheet, hacking in the many fixes required
|
||||||
|
* to make bottom sheets like this work.
|
||||||
|
* @author OxygenCobalt
|
||||||
|
*
|
||||||
|
* TODO: Implement hiding because I have to
|
||||||
|
*/
|
||||||
class PlaybackSheetBehavior<V : View>(context: Context, attributeSet: AttributeSet?) :
|
class PlaybackSheetBehavior<V : View>(context: Context, attributeSet: AttributeSet?) :
|
||||||
AuxioSheetBehavior<V>(context, attributeSet) {
|
AuxioSheetBehavior<V>(context, attributeSet) {
|
||||||
private var lastInsets: WindowInsets? = null
|
private var lastInsets: WindowInsets? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
isHideable = true
|
||||||
|
}
|
||||||
|
|
||||||
// Hack around issue where the playback sheet will try to intercept nested scrolling events
|
// Hack around issue where the playback sheet will try to intercept nested scrolling events
|
||||||
// before the queue sheet.
|
// before the queue sheet.
|
||||||
override fun onInterceptTouchEvent(
|
override fun onInterceptTouchEvent(
|
||||||
|
@ -58,13 +69,16 @@ class PlaybackSheetBehavior<V : View>(context: Context, attributeSet: AttributeS
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hideSafe() {
|
fun hideSafe() {
|
||||||
isDraggable = false
|
if (state != STATE_HIDDEN) {
|
||||||
isHideable = true
|
isDraggable = false
|
||||||
state = STATE_HIDDEN
|
state = STATE_HIDDEN
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unhideSafe() {
|
fun unhideSafe() {
|
||||||
isHideable = false
|
if (state == STATE_HIDDEN) {
|
||||||
isDraggable = true
|
state = STATE_COLLAPSED
|
||||||
|
isDraggable = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,8 @@ private constructor(
|
||||||
elevation = binding.context.getDimenSafe(R.dimen.elevation_normal) * 5
|
elevation = binding.context.getDimenSafe(R.dimen.elevation_normal) * 5
|
||||||
}
|
}
|
||||||
|
|
||||||
val isEnabled: Boolean
|
val isPrevious: Boolean
|
||||||
get() = binding.songDragHandle.isEnabled
|
get() = binding.songDragHandle.alpha == 0.5f
|
||||||
|
|
||||||
init {
|
init {
|
||||||
binding.body.background =
|
binding.body.background =
|
||||||
|
@ -87,17 +87,11 @@ private constructor(
|
||||||
|
|
||||||
binding.body.setOnClickListener { listener.onClick(this) }
|
binding.body.setOnClickListener { listener.onClick(this) }
|
||||||
|
|
||||||
if (item.previous) {
|
val alpha = if (item.previous) 0.5f else 1f
|
||||||
binding.songName.alpha = 0.5f
|
binding.songAlbumCover.alpha = alpha
|
||||||
binding.songInfo.alpha = 0.5f
|
binding.songName.alpha = alpha
|
||||||
binding.songAlbumCover.alpha = 0.5f
|
binding.songInfo.alpha = alpha
|
||||||
binding.songDragHandle.isEnabled = false
|
binding.songDragHandle.alpha = alpha
|
||||||
} else {
|
|
||||||
binding.songName.alpha = 1f
|
|
||||||
binding.songInfo.alpha = 1f
|
|
||||||
binding.songAlbumCover.alpha = 1f
|
|
||||||
binding.songDragHandle.isEnabled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Roll our own drag handlers as the default ones suck
|
// Roll our own drag handlers as the default ones suck
|
||||||
binding.songDragHandle.setOnTouchListener { _, motionEvent ->
|
binding.songDragHandle.setOnTouchListener { _, motionEvent ->
|
||||||
|
|
|
@ -40,7 +40,7 @@ class QueueDragCallback(private val playbackModel: QueueViewModel) : ItemTouchHe
|
||||||
viewHolder: RecyclerView.ViewHolder
|
viewHolder: RecyclerView.ViewHolder
|
||||||
): Int {
|
): Int {
|
||||||
val queueHolder = viewHolder as QueueSongViewHolder
|
val queueHolder = viewHolder as QueueSongViewHolder
|
||||||
return if (queueHolder.isEnabled) {
|
return if (!queueHolder.isPrevious) {
|
||||||
makeFlag(
|
makeFlag(
|
||||||
ItemTouchHelper.ACTION_STATE_DRAG, ItemTouchHelper.UP or ItemTouchHelper.DOWN) or
|
ItemTouchHelper.ACTION_STATE_DRAG, ItemTouchHelper.UP or ItemTouchHelper.DOWN) or
|
||||||
makeFlag(ItemTouchHelper.ACTION_STATE_SWIPE, ItemTouchHelper.START)
|
makeFlag(ItemTouchHelper.ACTION_STATE_SWIPE, ItemTouchHelper.START)
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.oxycblt.auxio.playback.queue
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import androidx.core.view.isInvisible
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
|
@ -31,6 +32,13 @@ import org.oxycblt.auxio.util.collectImmediately
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A [Fragment] that shows the queue and enables editing as well.
|
* A [Fragment] that shows the queue and enables editing as well.
|
||||||
|
*
|
||||||
|
* TODO: Improve index updates
|
||||||
|
*
|
||||||
|
* TODO: Test older versions
|
||||||
|
*
|
||||||
|
* TODO: Test restoration and song loss
|
||||||
|
*
|
||||||
* @author OxygenCobalt
|
* @author OxygenCobalt
|
||||||
*/
|
*/
|
||||||
class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemListener {
|
class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemListener {
|
||||||
|
@ -46,6 +54,14 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemList
|
||||||
binding.queueRecycler.apply {
|
binding.queueRecycler.apply {
|
||||||
adapter = queueAdapter
|
adapter = queueAdapter
|
||||||
touchHelper.attachToRecyclerView(this)
|
touchHelper.attachToRecyclerView(this)
|
||||||
|
addOnScrollListener(
|
||||||
|
object : RecyclerView.OnScrollListener() {
|
||||||
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
|
binding.queueDivider.isInvisible =
|
||||||
|
(layoutManager as LinearLayoutManager)
|
||||||
|
.findFirstCompletelyVisibleItemPosition() < 1
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ----
|
// --- VIEWMODEL SETUP ----
|
||||||
|
@ -78,11 +94,12 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemList
|
||||||
if (instructions.scrollTo != null) {
|
if (instructions.scrollTo != null) {
|
||||||
val binding = requireBinding()
|
val binding = requireBinding()
|
||||||
val lmm = binding.queueRecycler.layoutManager as LinearLayoutManager
|
val lmm = binding.queueRecycler.layoutManager as LinearLayoutManager
|
||||||
val indices =
|
val start = lmm.findFirstCompletelyVisibleItemPosition()
|
||||||
lmm.findFirstCompletelyVisibleItemPosition()..lmm
|
val end = lmm.findLastCompletelyVisibleItemPosition()
|
||||||
.findLastCompletelyVisibleItemPosition()
|
|
||||||
|
|
||||||
if (instructions.scrollTo !in indices) {
|
if (start != RecyclerView.NO_POSITION &&
|
||||||
|
end != RecyclerView.NO_POSITION &&
|
||||||
|
instructions.scrollTo !in start..end) {
|
||||||
binding.queueRecycler.scrollToPosition(instructions.scrollTo)
|
binding.queueRecycler.scrollToPosition(instructions.scrollTo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ class QueueViewModel : ViewModel(), PlaybackStateManager.Callback {
|
||||||
|
|
||||||
playbackManager.moveQueueItem(adapterFrom, adapterTo)
|
playbackManager.moveQueueItem(adapterFrom, adapterTo)
|
||||||
|
|
||||||
return false
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun finishInstructions() {
|
fun finishInstructions() {
|
||||||
|
|
|
@ -25,7 +25,6 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import com.google.android.material.bottomsheet.NeoBottomSheetBehavior
|
import com.google.android.material.bottomsheet.NeoBottomSheetBehavior
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import org.oxycblt.auxio.util.coordinatorLayoutBehavior
|
import org.oxycblt.auxio.util.coordinatorLayoutBehavior
|
||||||
import org.oxycblt.auxio.util.logD
|
|
||||||
import org.oxycblt.auxio.util.replaceSystemBarInsetsCompat
|
import org.oxycblt.auxio.util.replaceSystemBarInsetsCompat
|
||||||
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||||
|
|
||||||
|
@ -61,7 +60,6 @@ class BottomSheetContentBehavior<V : View>(context: Context, attributeSet: Attri
|
||||||
layoutContent(child)
|
layoutContent(child)
|
||||||
|
|
||||||
if (!setup) {
|
if (!setup) {
|
||||||
|
|
||||||
child.setOnApplyWindowInsetsListener { v, insets ->
|
child.setOnApplyWindowInsetsListener { v, insets ->
|
||||||
lastInsets = insets
|
lastInsets = insets
|
||||||
val dep = dep ?: return@setOnApplyWindowInsetsListener insets
|
val dep = dep ?: return@setOnApplyWindowInsetsListener insets
|
||||||
|
@ -94,8 +92,6 @@ class BottomSheetContentBehavior<V : View>(context: Context, attributeSet: Attri
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun layoutContent(child: View) {
|
private fun layoutContent(child: View) {
|
||||||
logD("Measure")
|
|
||||||
|
|
||||||
child.layout(0, 0, child.measuredWidth, child.measuredHeight)
|
child.layout(0, 0, child.measuredWidth, child.measuredHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,8 +122,6 @@ class BottomSheetContentBehavior<V : View>(context: Context, attributeSet: Attri
|
||||||
child: V,
|
child: V,
|
||||||
dependency: View
|
dependency: View
|
||||||
): Boolean {
|
): Boolean {
|
||||||
logD("Dependent view changed $child")
|
|
||||||
|
|
||||||
val behavior = dependency.coordinatorLayoutBehavior as NeoBottomSheetBehavior
|
val behavior = dependency.coordinatorLayoutBehavior as NeoBottomSheetBehavior
|
||||||
val consumed = behavior.calculateConsumedByBar()
|
val consumed = behavior.calculateConsumedByBar()
|
||||||
if (consumed < Int.MIN_VALUE) {
|
if (consumed < Int.MIN_VALUE) {
|
||||||
|
@ -135,8 +129,6 @@ class BottomSheetContentBehavior<V : View>(context: Context, attributeSet: Attri
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consumed != lastConsumed) {
|
if (consumed != lastConsumed) {
|
||||||
logD("Dependent view changed important $child")
|
|
||||||
|
|
||||||
lastConsumed = consumed
|
lastConsumed = consumed
|
||||||
|
|
||||||
val insets = lastInsets
|
val insets = lastInsets
|
||||||
|
|
|
@ -95,16 +95,14 @@ class WidgetComponent(private val context: Context) :
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize the image in a such a way that we don't hit the RemoteView size
|
// Resize the image in a such a way that we don't hit the RemoteView size
|
||||||
// limit. The limit is technically the byte-size of an RGB_8888 bitmap 1.5x
|
// limit, which is the size of an RGB_8888 bitmap 1.5x the screen size. Note
|
||||||
// the screen size, but the size of a RemoteView can for some reason be 10x
|
// that we actually set the limit to be half the memory limit so that it's
|
||||||
// the size of the binded bitmaps, which means we need to heavily reduce
|
// less likely for us to hit it. it to really ensure we don't hit the limit.
|
||||||
// our image size as to make sure we stay around an order of magnitude below
|
// This also creates the consistent sizes required for round bitmaps.
|
||||||
// the memory limit. This fixed size is also needed to ensure consistent
|
|
||||||
// outlines on rounded images.
|
|
||||||
val metrics = context.resources.displayMetrics
|
val metrics = context.resources.displayMetrics
|
||||||
val sw = metrics.widthPixels
|
val sw = metrics.widthPixels
|
||||||
val sh = metrics.heightPixels
|
val sh = metrics.heightPixels
|
||||||
builder.size((sqrt((6f * sw * sh)) / 8f).toInt())
|
builder.size((sqrt((6f * sw * sh) / 8f)).toInt())
|
||||||
|
|
||||||
return if (cornerRadius > 0) {
|
return if (cornerRadius > 0) {
|
||||||
this@WidgetComponent.logD("Loading round covers: $cornerRadius")
|
this@WidgetComponent.logD("Loading round covers: $cornerRadius")
|
||||||
|
|
|
@ -63,7 +63,7 @@ class WidgetProvider : AppWidgetProvider() {
|
||||||
SizeF(180f, 272f) to createMediumWidget(context, state),
|
SizeF(180f, 272f) to createMediumWidget(context, state),
|
||||||
SizeF(272f, 272f) to createLargeWidget(context, state))
|
SizeF(272f, 272f) to createLargeWidget(context, state))
|
||||||
|
|
||||||
AppWidgetManager.getInstance(context).applyViewsCompat(context, views)
|
AppWidgetManager.getInstance(context).updateAppWidgetCompat(context, views)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -114,7 +114,7 @@ class WidgetProvider : AppWidgetProvider() {
|
||||||
context.sendBroadcast(intent)
|
context.sendBroadcast(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun AppWidgetManager.applyViewsCompat(
|
private fun AppWidgetManager.updateAppWidgetCompat(
|
||||||
context: Context,
|
context: Context,
|
||||||
views: Map<SizeF, RemoteViews>
|
views: Map<SizeF, RemoteViews>
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:alpha="0.24" android:color="?attr/colorOnSurface" android:state_enabled="false" />
|
||||||
<item android:color="?attr/colorPrimary" android:state_activated="true" />
|
<item android:color="?attr/colorPrimary" android:state_activated="true" />
|
||||||
<item android:color="?android:attr/textColorPrimary" />
|
<item android:color="?android:attr/textColorPrimary" />
|
||||||
</selector>
|
</selector>
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:alpha="0.24" android:color="?attr/colorOnSurface" android:state_enabled="false" />
|
||||||
<item android:color="?attr/colorPrimary" android:state_activated="true" />
|
<item android:color="?attr/colorPrimary" android:state_activated="true" />
|
||||||
<item android:color="?android:attr/textColorSecondary" />
|
<item android:color="?android:attr/textColorSecondary" />
|
||||||
</selector>
|
</selector>
|
|
@ -17,6 +17,7 @@
|
||||||
tools:listitem="@layout/item_queue_song" />
|
tools:listitem="@layout/item_queue_song" />
|
||||||
|
|
||||||
<com.google.android.material.divider.MaterialDivider
|
<com.google.android.material.divider.MaterialDivider
|
||||||
|
android:id="@+id/queue_divider"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
|
|
@ -32,51 +32,51 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?attr/selectableItemBackground">
|
android:background="?attr/selectableItemBackground">
|
||||||
|
|
||||||
<org.oxycblt.auxio.image.StyledImageView
|
<org.oxycblt.auxio.image.StyledImageView
|
||||||
android:id="@+id/song_album_cover"
|
android:id="@+id/song_album_cover"
|
||||||
style="@style/Widget.Auxio.Image.Small"
|
style="@style/Widget.Auxio.Image.Small"
|
||||||
android:layout_margin="@dimen/spacing_medium"
|
android:layout_margin="@dimen/spacing_medium"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:staticIcon="@drawable/ic_song_24" />
|
tools:staticIcon="@drawable/ic_song_24" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/song_name"
|
android:id="@+id/song_name"
|
||||||
style="@style/Widget.Auxio.TextView.Item.Primary"
|
style="@style/Widget.Auxio.TextView.Item.Primary"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="@dimen/spacing_medium"
|
android:layout_marginEnd="@dimen/spacing_medium"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/song_info"
|
app:layout_constraintBottom_toTopOf="@+id/song_info"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/song_drag_handle"
|
app:layout_constraintEnd_toStartOf="@+id/song_drag_handle"
|
||||||
app:layout_constraintStart_toEndOf="@+id/song_album_cover"
|
app:layout_constraintStart_toEndOf="@+id/song_album_cover"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintVertical_chainStyle="packed"
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
tools:text="Song Name" />
|
tools:text="Song Name" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/song_info"
|
android:id="@+id/song_info"
|
||||||
style="@style/Widget.Auxio.TextView.Item.Secondary"
|
style="@style/Widget.Auxio.TextView.Item.Secondary"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="@dimen/spacing_medium"
|
android:layout_marginEnd="@dimen/spacing_medium"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/song_drag_handle"
|
app:layout_constraintEnd_toStartOf="@+id/song_drag_handle"
|
||||||
app:layout_constraintStart_toEndOf="@+id/song_album_cover"
|
app:layout_constraintStart_toEndOf="@+id/song_album_cover"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/song_name"
|
app:layout_constraintTop_toBottomOf="@+id/song_name"
|
||||||
tools:text="Artist / Album" />
|
tools:text="Artist / Album" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/song_drag_handle"
|
android:id="@+id/song_drag_handle"
|
||||||
style="@style/Widget.Auxio.Button.Icon.Small"
|
style="@style/Widget.Auxio.Button.Icon.Small"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="@dimen/spacing_mid_medium"
|
android:layout_marginEnd="@dimen/spacing_mid_medium"
|
||||||
android:contentDescription="@string/desc_queue_handle"
|
android:contentDescription="@string/desc_queue_handle"
|
||||||
app:icon="@drawable/ic_handle_24"
|
app:icon="@drawable/ic_handle_24"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/song_album_cover"
|
app:layout_constraintBottom_toBottomOf="@+id/song_album_cover"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@+id/song_album_cover" />
|
app:layout_constraintTop_toTopOf="@+id/song_album_cover" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue