ui: general cleanup

Clean up a bunch of UI issues that have accumulated.
This commit is contained in:
OxygenCobalt 2022-02-23 15:22:41 -07:00
parent 22258a3e6b
commit 87035805d2
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
31 changed files with 50 additions and 72 deletions

View file

@ -204,7 +204,7 @@ to when using gesture navigation
- Fixed issue where the scroll thumb would briefly display on the Songs UI
- Fixed issue where fast scrolling could be triggered outside the bounds of the indicators
- Fixed issue where the wrong playing item would be highlighted if the names were identical
- Fixed a crash when the thumb was moved above the fast scroller [Backported to 1.3.3, included in this release officially]
- Fixed a crash when the thumb was moved above the fast scroller [Back-ported to 1.3.3, included in this release officially]
#### Dev/Meta
- Migrated fully to material design

View file

@ -101,7 +101,7 @@ private val ACCENT_PRIMARY_COLORS = arrayOf(
/**
* The data object for an accent. In the UI this is known as a "Color Scheme."
* This can be nominally used to gleam some attributes about a given color scheme, but this
* is not recommended. Attributes are usually the better option in nearly all cases.
* is not recommended. Attributes are the better option in nearly all cases.
*
* @property name The name of this accent
* @property theme The theme resource for this accent

View file

@ -5,7 +5,7 @@ import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import androidx.annotation.StyleRes
import androidx.annotation.AttrRes
import androidx.appcompat.widget.AppCompatTextView
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
@ -28,7 +28,7 @@ import java.lang.Exception
class DetailAppBarLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@StyleRes defStyleAttr: Int = -1
@AttrRes defStyleAttr: Int = 0
) : EdgeAppBarLayout(context, attrs, defStyleAttr) {
private var mTitleView: AppCompatTextView? = null
private var mRecycler: RecyclerView? = null
@ -109,7 +109,7 @@ class DetailAppBarLayout @JvmOverloads constructor(
titleView?.alpha = it.animatedValue as Float
}
duration = resources.getInteger(R.integer.app_bar_elevation_anim_duration).toLong()
duration = resources.getInteger(R.integer.detail_app_bar_title_anim_duration).toLong()
start()
}

View file

@ -22,6 +22,7 @@ import android.content.Context
import android.util.AttributeSet
import android.view.WindowInsets
import android.widget.FrameLayout
import androidx.annotation.AttrRes
import androidx.core.view.updatePadding
import org.oxycblt.auxio.util.systemBarInsetsCompat
@ -32,7 +33,7 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
class FloatingActionButtonContainer @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = -1
@AttrRes defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
init {
clipToPadding = false

View file

@ -32,6 +32,7 @@ import android.view.ViewGroup
import android.view.WindowInsets
import android.widget.FrameLayout
import android.widget.TextView
import androidx.annotation.AttrRes
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.math.MathUtils
import androidx.core.view.isInvisible
@ -77,7 +78,7 @@ import kotlin.math.abs
class FastScrollRecyclerView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = -1
@AttrRes defStyleAttr: Int = 0
) : RecyclerView(context, attrs, defStyleAttr) {
/** Callback to provide a string to be shown on the popup when an item is passed */
var popupProvider: ((Int) -> String)? = null

View file

@ -28,7 +28,7 @@ import androidx.annotation.StringRes
// --- MUSIC MODELS ---
/**
* The template for all items in Auxio.
* The base for all items in Auxio.
*/
sealed class Item {
/** A unique ID for this item. ***THIS IS NOT A MEDIASTORE ID!** */
@ -36,7 +36,7 @@ sealed class Item {
}
/**
* A [Item] variant that represents a music item.
* [Item] variant that represents a music item.
* @property name
*/
sealed class Music : Item() {

View file

@ -41,7 +41,7 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
class PlaybackBarView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = -1
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
private val binding = ViewPlaybackBarBinding.inflate(context.inflater, this, true)

View file

@ -5,6 +5,7 @@ import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.RectF
import android.util.AttributeSet
import androidx.annotation.AttrRes
import androidx.appcompat.widget.AppCompatImageButton
import org.oxycblt.auxio.R
import org.oxycblt.auxio.util.getDimenSizeSafe
@ -25,7 +26,7 @@ import org.oxycblt.auxio.util.getDrawableSafe
class PlaybackButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = -1
@AttrRes defStyleAttr: Int = 0
) : AppCompatImageButton(context, attrs, defStyleAttr) {
private val iconSize = context.getDimenSizeSafe(R.dimen.size_playback_icon)
private val centerMatrix = Matrix()
@ -33,7 +34,7 @@ class PlaybackButton @JvmOverloads constructor(
private val matrixDst = RectF()
private val indicatorDrawable = context.getDrawableSafe(R.drawable.ui_indicator)
var hasIndicator = false
private var hasIndicator = false
set(value) {
field = value
invalidate()

View file

@ -42,7 +42,7 @@ import org.oxycblt.auxio.util.stateList
class PlaybackSeekBar @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleRes: Int = -1
defStyleRes: Int = 0
) : ConstraintLayout(context, attrs, defStyleRes), Slider.OnChangeListener, Slider.OnSliderTouchListener {
private val binding = ViewSeekBarBinding.inflate(context.inflater, this, true)
private val isSeeking: Boolean get() = binding.playbackDurationCurrent.isActivated

View file

@ -18,25 +18,28 @@
package org.oxycblt.auxio.settings.pref
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.TypedArray
import android.util.AttributeSet
import androidx.preference.DialogPreference
import androidx.preference.Preference
import org.oxycblt.auxio.R
import androidx.preference.R as prefR
class IntListPreference @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = prefR.attr.dialogPreferenceStyle,
defStyleAttr: Int = androidx.preference.R.attr.dialogPreferenceStyle,
defStyleRes: Int = 0
) : DialogPreference(context, attrs, defStyleAttr, defStyleRes) {
// Reflect into Preference to get the (normally inaccessible) default value.
private val defValueField = Preference::class.java.getDeclaredField("mDefaultValue").apply {
isAccessible = true
}
val entries: Array<CharSequence>
val values: IntArray
private var currentValue: Int? = null
private val defValue: Int
private val defValue: Int get() = defValueField.get(this) as Int
init {
val prefAttrs = context.obtainStyledAttributes(
@ -49,8 +52,6 @@ class IntListPreference @JvmOverloads constructor(
prefAttrs.getResourceId(R.styleable.IntListPreference_entryValues, -1)
)
defValue = prefAttrs.getInt(prefR.styleable.Preference_defaultValue, Int.MIN_VALUE)
prefAttrs.recycle()
summaryProvider = IntListSummaryProvider()
@ -96,7 +97,6 @@ class IntListPreference @JvmOverloads constructor(
}
}
@SuppressLint("PrivateResource")
private inner class IntListSummaryProvider : SummaryProvider<IntListPreference> {
override fun provideSummary(preference: IntListPreference): CharSequence {
val index = getValueIndex()
@ -105,7 +105,8 @@ class IntListPreference @JvmOverloads constructor(
return entries[index]
}
return context.getString(prefR.string.not_set)
// Usually an invalid state, don't bother translating
return "<not set>"
}
}
}

View file

@ -24,7 +24,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.view.WindowInsets
import androidx.annotation.StyleRes
import androidx.annotation.AttrRes
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.updatePadding
@ -41,7 +41,7 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
open class EdgeAppBarLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@StyleRes defStyleAttr: Int = -1
@AttrRes defStyleAttr: Int = 0
) : AppBarLayout(context, attrs, defStyleAttr) {
private var scrollingChild: View? = null
private val tConsumed = IntArray(2)

View file

@ -21,6 +21,7 @@ package org.oxycblt.auxio.ui
import android.content.Context
import android.util.AttributeSet
import android.view.WindowInsets
import androidx.annotation.AttrRes
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.children
@ -33,7 +34,7 @@ import androidx.core.view.children
class EdgeCoordinatorLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = -1
@AttrRes defStyleAttr: Int = 0
) : CoordinatorLayout(context, attrs, defStyleAttr) {
override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
for (child in children) {

View file

@ -21,6 +21,7 @@ package org.oxycblt.auxio.ui
import android.content.Context
import android.util.AttributeSet
import android.view.WindowInsets
import androidx.annotation.AttrRes
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.util.systemBarInsetsCompat
@ -31,7 +32,7 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
class EdgeRecyclerView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = -1
@AttrRes defStyleAttr: Int = 0
) : RecyclerView(context, attrs, defStyleAttr) {
override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
updatePadding(bottom = insets.systemBarInsetsCompat.bottom)

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight"
android:radius="@dimen/size_large_unbounded_ripple" />
android:radius="24dp" />

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight"
android:radius="@dimen/size_small_unbounded_ripple" />
android:radius="20dp" />

View file

@ -122,7 +122,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_loop"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_medium"
@ -136,7 +135,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_skip_prev"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/desc_skip_prev"
@ -164,7 +162,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_skip_next"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/desc_skip_next"
@ -177,7 +174,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_shuffle"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/desc_shuffle"

View file

@ -115,7 +115,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_loop"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_large"
@ -130,7 +129,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_skip_prev"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_large"
@ -157,7 +155,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_skip_next"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_large"
@ -170,7 +167,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_shuffle"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_large"

View file

@ -102,7 +102,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_loop"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_large"
@ -117,7 +116,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_skip_prev"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_large"
@ -144,7 +142,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_skip_next"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_large"
@ -157,7 +154,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_shuffle"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_large"

View file

@ -61,7 +61,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_skip_prev"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_small"
@ -75,7 +74,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_play_pause"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_small"
@ -89,7 +87,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_skip_next"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_small"

View file

@ -57,9 +57,8 @@
app:layout_constraintTop_toBottomOf="@+id/playback_song"
tools:text="Artist Name / Album Name" />
<ImageButton
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_skip_prev"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_small"
@ -71,9 +70,8 @@
app:layout_constraintStart_toEndOf="@+id/playback_song"
app:layout_constraintTop_toTopOf="@+id/playback_play_pause" />
<ImageButton
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_play_pause"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_small"
@ -87,7 +85,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_skip_next"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_small"

View file

@ -32,13 +32,7 @@
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_medium"
app:cardBackgroundColor="?attr/colorSurface"
app:cardCornerRadius="0dp"
app:cardElevation="0dp"
app:strokeColor="@color/mtrl_btn_stroke_color_selector"
app:strokeWidth="1dp"
tools:ignore="PrivateResource">
android:layout_margin="@dimen/spacing_medium">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"

View file

@ -28,10 +28,12 @@
<ImageButton
android:id="@+id/excluded_clear"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_small"
android:minHeight="@dimen/size_btn_small"
android:minWidth="@dimen/size_btn_small"
android:background="@drawable/ui_unbounded_ripple"
android:contentDescription="@string/desc_blacklist_delete"
android:src="@drawable/ic_clear"
app:layout_constraintBottom_toBottomOf="parent"

View file

@ -60,7 +60,6 @@
<org.oxycblt.auxio.playback.PlaybackButton
android:id="@+id/playback_play_pause"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_small"

View file

@ -16,6 +16,7 @@
android:paddingStart="@dimen/spacing_small"
android:paddingEnd="@dimen/spacing_small"
app:labelBehavior="gone"
app:labelStyle="@style/TextAppearance.Auxio.BodySmall"
android:valueFrom="0"
android:valueTo="1"
app:thumbRadius="@dimen/slider_thumb_radius"

View file

@ -172,12 +172,10 @@
<string name="fmt_songs_loaded">已加载 %d 首曲目</string>
<plurals name="fmt_song_count">
<item quantity="one">%d 首歌曲</item>
<item quantity="other">"%d 首歌曲"</item>
</plurals>
<plurals name="fmt_album_count">
<item quantity="one">%d 张专辑</item>
<item quantity="other">"%d 张专辑"</item>
</plurals>
</resources>

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Spacing Namespace | Dimens for padding/margin attributes -->
<dimen name="spacing_tiny">4dp</dimen>
<dimen name="spacing_small">8dp</dimen>
<dimen name="spacing_medium">16dp</dimen>
<dimen name="spacing_mid_large">24dp</dimen>
@ -16,9 +17,6 @@
<dimen name="size_cover_mid_huge">192dp</dimen>
<dimen name="size_cover_huge">256dp</dimen>
<dimen name="size_small_unbounded_ripple">20dp</dimen>
<dimen name="size_large_unbounded_ripple">24dp</dimen>
<dimen name="size_track_number">32dp</dimen>
<dimen name="size_playback_icon">32dp</dimen>

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="detail_app_bar_title_anim_duration">150</integer>
<!-- Preference values -->
<string-array name="entries_theme">
<item>@string/set_theme_auto</item>

View file

@ -151,10 +151,6 @@
<!-- BUTTON STYLES -->
<style name="Widget.Auxio.Button.Unbounded" parent="Widget.AppCompat.Button.Borderless">
<item name="android:padding">0dp</item>
</style>
<style name="Widget.Auxio.Button.Primary" parent="Widget.Material3.Button">
<item name="android:textAppearance">@style/TextAppearance.Auxio.LabelLarger</item>
</style>

View file

@ -1,5 +1,5 @@
- Redesigned the detail UIs
- Navigation is much more fluid and straightfoward
- Navigation is much more fluid and straightforward
- Search has been moved to a dedicated tab
- Added search filtering
- Fixed issue where audio focus would resume playback when it shouldn't

View file

@ -7,7 +7,7 @@ These will likely be accepted as long as they do not cause too much harm to the
## New Customizations/Options
While I do like adding new behavior/UI customizations, these will be looked at more closely as certain additions can cause harm to the apps UI/UX while not providing alot of benefit. These tend to be accepted however.
## Feature Addtions and UI Changes
## Feature Additions and UI Changes
These arent as likely to be accepted. As I said, I do not want Auxio to become overly bloated with features that are rarely used, therefore I only tend to accept features that:
- Benefit **my own** usage
@ -22,6 +22,6 @@ Feel free to fork Auxio to add your own feature set however.
- Recently added list [#18] (Out of scope)
- Lyrics [#19] (Out of scope)
- Tag editing [#33] (Out of scope)
- Gapless Playback [#35] (Technical issues)
- Gapless Playback [#35] (Technical issues, may change in the future)
- Reduce leading instrument [#45] (Technical issues, Out of scope)
- Opening music through a provider [#30] (Out of scope)

View file

@ -52,13 +52,13 @@ is separated into three phases:
- Set up the UI
- Set up ViewModel instances and LiveData observers
`findViewById` is to **only** be used when interfacing with non-Auxio views. Otherwise, viewbinding should be
used in all cases. If one needs to keep track of a viewbinding outside of `onCreateView`, then one can declare
`findViewById` is to **only** be used when interfacing with non-Auxio views. Otherwise, view-binding should be
used in all cases. If one needs to keep track of a view-binding outside of `onCreateView`, then one can declare
a binding `by memberBinding(BindingClass::inflate)` in order to have a binding that properly disposes itself
on lifecycle events.
At times it may be more appropriate to use a `View` instead of a full blown fragment. This is okay as long as
viewbinding is still used.
view-binding is still used.
When creating a ViewHolder for a `RecyclerView`, one should use `BaseViewHolder` to standardize the binding process
and automate some code shared across all ViewHolders. The only exceptions to this case are for ViewHolders that