ui: fix lollipop bugs
Fix more lollipop bugs, as I usually do. Except for the drawing issues I may or may not have produced. Don't really care enough to fix them though.
This commit is contained in:
parent
e12c7cb419
commit
5978e124d2
14 changed files with 85 additions and 93 deletions
|
@ -44,9 +44,6 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
|
|||
*
|
||||
* TODO: Add multi-select
|
||||
*
|
||||
* LEFT-OFF: Add RecyclerView styles, queue issue is caused by tiny scroll and then replace op, not
|
||||
* enough to change scroll apparently
|
||||
*
|
||||
* @author OxygenCobalt
|
||||
*/
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
|
|
@ -128,9 +128,6 @@ private constructor(
|
|||
|
||||
binding.background.isInvisible = true
|
||||
|
||||
binding.songName.requestLayout()
|
||||
binding.songInfo.requestLayout()
|
||||
|
||||
binding.body.setOnClickListener { listener.onClick(this) }
|
||||
|
||||
// Roll our own drag handlers as the default ones suck
|
||||
|
|
|
@ -49,12 +49,14 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemList
|
|||
binding.queueRecycler.apply {
|
||||
adapter = queueAdapter
|
||||
touchHelper.attachToRecyclerView(this)
|
||||
|
||||
// Sometimes the scroll can change without the listener being updated, so we also
|
||||
// check for relayout events.
|
||||
addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> invalidateDivider() }
|
||||
addOnScrollListener(
|
||||
object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
binding.queueDivider.isInvisible =
|
||||
(layoutManager as LinearLayoutManager)
|
||||
.findFirstCompletelyVisibleItemPosition() < 1
|
||||
invalidateDivider()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -78,6 +80,8 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemList
|
|||
}
|
||||
|
||||
private fun updateQueue(queue: List<Song>, index: Int) {
|
||||
val binding = requireBinding()
|
||||
|
||||
val replaceQueue = queueModel.replaceQueue
|
||||
if (replaceQueue == true) {
|
||||
logD("Replacing queue")
|
||||
|
@ -87,11 +91,14 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemList
|
|||
queueAdapter.data.submitList(queue)
|
||||
}
|
||||
|
||||
binding.queueDivider.isInvisible =
|
||||
(binding.queueRecycler.layoutManager as LinearLayoutManager)
|
||||
.findFirstCompletelyVisibleItemPosition() < 1
|
||||
|
||||
queueModel.finishReplace()
|
||||
|
||||
val scrollTo = queueModel.scrollTo
|
||||
if (scrollTo != null) {
|
||||
val binding = requireBinding()
|
||||
val lmm = binding.queueRecycler.layoutManager as LinearLayoutManager
|
||||
val start = lmm.findFirstCompletelyVisibleItemPosition()
|
||||
val end = lmm.findLastCompletelyVisibleItemPosition()
|
||||
|
@ -106,4 +113,11 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemList
|
|||
|
||||
queueAdapter.updateIndex(index)
|
||||
}
|
||||
|
||||
private fun invalidateDivider() {
|
||||
val binding = requireBinding()
|
||||
binding.queueDivider.isInvisible =
|
||||
(binding.queueRecycler.layoutManager as LinearLayoutManager)
|
||||
.findFirstCompletelyVisibleItemPosition() < 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
package org.oxycblt.auxio.settings
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.annotation.DrawableRes
|
||||
|
@ -154,45 +153,38 @@ class SettingsListFragment : PreferenceFragmentCompat() {
|
|||
if (!preference.isVisible) return
|
||||
|
||||
if (preference is PreferenceCategory) {
|
||||
for (child in preference.children) {
|
||||
setupPreference(child)
|
||||
}
|
||||
preference.children.forEach(::setupPreference)
|
||||
return
|
||||
}
|
||||
|
||||
preference.apply {
|
||||
when (key) {
|
||||
context.getString(R.string.set_key_theme) -> {
|
||||
// Android 12 is the first version I deem to have universal dark and light
|
||||
// mode toggles. No need for our setting.
|
||||
isVisible = Build.VERSION.SDK_INT < Build.VERSION_CODES.S
|
||||
when (preference.key) {
|
||||
context.getString(R.string.set_key_theme) -> {
|
||||
preference.onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _, value ->
|
||||
AppCompatDelegate.setDefaultNightMode(value as Int)
|
||||
true
|
||||
}
|
||||
}
|
||||
context.getString(R.string.set_key_accent) -> {
|
||||
preference.summary = context.getString(settings.accent.name)
|
||||
}
|
||||
context.getString(R.string.set_key_black_theme) -> {
|
||||
preference.onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _, _ ->
|
||||
if (context.isNight) {
|
||||
context.recreate()
|
||||
}
|
||||
|
||||
onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _, value ->
|
||||
AppCompatDelegate.setDefaultNightMode(value as Int)
|
||||
true
|
||||
}
|
||||
}
|
||||
context.getString(R.string.set_key_accent) -> {
|
||||
summary = context.getString(settings.accent.name)
|
||||
}
|
||||
context.getString(R.string.set_key_black_theme) -> {
|
||||
onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _, _ ->
|
||||
if (context.isNight) {
|
||||
context.recreate()
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
context.getString(R.string.set_key_show_covers),
|
||||
context.getString(R.string.set_key_quality_covers) -> {
|
||||
onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _, _ ->
|
||||
Coil.imageLoader(context).apply { this.memoryCache?.clear() }
|
||||
true
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
context.getString(R.string.set_key_show_covers),
|
||||
context.getString(R.string.set_key_quality_covers) -> {
|
||||
preference.onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _, _ ->
|
||||
Coil.imageLoader(context).memoryCache?.clear()
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.oxycblt.auxio.ui
|
|||
import android.content.Context
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.os.Build
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -79,8 +80,12 @@ abstract class AuxioSheetBehavior<V : View>(context: Context, attributeSet: Attr
|
|||
context.getAttrColorCompat(R.attr.colorSurface).defaultColor),
|
||||
sheetBackgroundDrawable))
|
||||
|
||||
// Try to disable drop shadows if possible.
|
||||
disableDropShadowCompat()
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
val transparent =
|
||||
context.getColorCompat(android.R.color.transparent).defaultColor
|
||||
outlineAmbientShadowColor = transparent
|
||||
outlineSpotShadowColor = transparent
|
||||
}
|
||||
|
||||
setOnApplyWindowInsetsListener(::applyWindowInsets)
|
||||
}
|
||||
|
|
|
@ -55,11 +55,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
|||
|
||||
override fun onScrolled(dx: Int, dy: Int) {
|
||||
super.onScrolled(dx, dy)
|
||||
|
||||
val manager = layoutManager as LinearLayoutManager
|
||||
topDivider.isInvisible = manager.findFirstCompletelyVisibleItemPosition() < 1
|
||||
bottomDivider.isInvisible =
|
||||
manager.findLastCompletelyVisibleItemPosition() == (manager.itemCount - 1)
|
||||
invalidateDividers()
|
||||
}
|
||||
|
||||
override fun onMeasure(widthSpec: Int, heightSpec: Int) {
|
||||
|
@ -88,5 +84,13 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
|||
super.onLayout(changed, l, t, r, b)
|
||||
topDivider.layout(l, spacingMedium, r, spacingMedium + topDivider.measuredHeight)
|
||||
bottomDivider.layout(l, measuredHeight - bottomDivider.measuredHeight, r, b)
|
||||
invalidateDividers()
|
||||
}
|
||||
|
||||
private fun invalidateDividers() {
|
||||
val manager = layoutManager as LinearLayoutManager
|
||||
topDivider.isInvisible = manager.findFirstCompletelyVisibleItemPosition() < 1
|
||||
bottomDivider.isInvisible =
|
||||
manager.findLastCompletelyVisibleItemPosition() == (manager.itemCount - 1)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,18 +47,6 @@ import kotlinx.coroutines.flow.combine
|
|||
import kotlinx.coroutines.launch
|
||||
import org.oxycblt.auxio.R
|
||||
|
||||
/**
|
||||
* Disables drop shadows on a view programmatically in a version-compatible manner. This only works
|
||||
* on Android 9 and above. Below that version, shadows will remain visible.
|
||||
*/
|
||||
fun View.disableDropShadowCompat() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
val transparent = context.getColorCompat(android.R.color.transparent).defaultColor
|
||||
outlineAmbientShadowColor = transparent
|
||||
outlineSpotShadowColor = transparent
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the point given by [x] and [y] falls within this view.
|
||||
* @param minTouchTargetSize The minimum touch size, independent of the view's size (Optional)
|
||||
|
|
|
@ -34,8 +34,7 @@ fun Any.logD(obj: Any?) = logD("$obj")
|
|||
* objects
|
||||
*/
|
||||
fun Any.logD(msg: String) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
basedCopyleftNotice()
|
||||
if (BuildConfig.DEBUG && !basedCopyleftNotice()) {
|
||||
Log.d(autoTag, msg)
|
||||
}
|
||||
}
|
||||
|
@ -58,18 +57,6 @@ fun Any.logEOrThrow(msg: String) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs an error in production while still throwing it in debug mode. This is useful for
|
||||
* non-showstopper bugs that I would still prefer to be caught in debug mode.
|
||||
*/
|
||||
fun Throwable.logTraceOrThrow() {
|
||||
if (BuildConfig.DEBUG) {
|
||||
throw this
|
||||
} else {
|
||||
logE(stackTraceToString())
|
||||
}
|
||||
}
|
||||
|
||||
/** Automatically creates a tag that identifies the object currently logging. */
|
||||
private val Any.autoTag: String
|
||||
get() = "Auxio.${this::class.simpleName ?: "Anonymous Object"}"
|
||||
|
@ -84,31 +71,33 @@ private val Any.autoTag: String
|
|||
*
|
||||
* JUNE 1989 TIANAMEN SQUARE PROTESTS AND MASSACRE 六四事件
|
||||
*
|
||||
* KASHMIR INDEPENDENCE MOVEMENT
|
||||
* 2022 RUSSIAN INVASION OF UKRAINE Вторжение России на Украину
|
||||
*
|
||||
* WOMEN'S RIGHTS IN THE ISLAMIC REPUBLIC OF IRAN حقوق زنان در ایران
|
||||
*
|
||||
* FREE TIBET 西藏自由
|
||||
*
|
||||
* 1971 BANGLADESHI GENOCIDE BY PAKISTAN
|
||||
*
|
||||
* 2022 RUSSIAN INVASION OF UKRAINE Вторжение России на Украину
|
||||
*
|
||||
* UYGHUR GENOCIDE/XINJIANG INTERNMENT CAMPS 新疆种族灭绝指控/新疆再教育營
|
||||
*
|
||||
* KURDISTAN WORKERS PARTY KÜRDISTAN İŞÇI PARTISI (PKK)
|
||||
* KASHMIR INDEPENDENCE MOVEMENT
|
||||
*
|
||||
* TORTURE AND ASSASSINATION OF JAMAL KHASHOGGI مقتل جمال خاشقجي
|
||||
* FREE TIBET 西藏自由
|
||||
*
|
||||
* 1915-1916 ARMENIAN GENOCIDE Ermeni Kırımı
|
||||
*
|
||||
* 2018 TORTURE AND ASSASSINATION OF JAMAL KHASHOGGI مقتل جمال خاشقجي
|
||||
*
|
||||
* UNITED ARAB EMIRATES ENSLAVED MIGRANT WORKERS
|
||||
*/
|
||||
@Suppress("KotlinConstantConditions")
|
||||
private fun basedCopyleftNotice() {
|
||||
private fun basedCopyleftNotice(): Boolean {
|
||||
if (BuildConfig.APPLICATION_ID != "org.oxycblt.auxio" &&
|
||||
BuildConfig.APPLICATION_ID != "org.oxycblt.auxio.debug") {
|
||||
Log.d(
|
||||
"Auxio Project",
|
||||
"Friendly reminder: Auxio is licensed under the " +
|
||||
"GPLv3 and all derivative apps must be made open source!")
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Widget.Auxio.RecyclerView.Grid" parent="Widget.Auxio.RecyclerView.Grid.Base">
|
||||
<item name="spanCount">3</item>
|
||||
</style>
|
||||
|
|
4
app/src/main/res/values-v31/settings.xml
Normal file
4
app/src/main/res/values-v31/settings.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="enable_theme_settings">false</bool>
|
||||
</resources>
|
|
@ -1,5 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="enable_theme_settings">true</bool>
|
||||
|
||||
<!-- Note: The old way of naming keys was to prefix them with KEY_. Now it's to prefix them with auxio_. -->
|
||||
<string name="set_key_theme" translatable="false">KEY_THEME2</string>
|
||||
<string name="set_key_black_theme" translatable="false">KEY_BLACK_THEME</string>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<resources>
|
||||
<!-- Master parent theme -->
|
||||
<style name="Theme.Auxio" parent="Theme.Material3.DynamicColors.DayNight" />
|
||||
<!-- Adds nicer selector attributes not supported on lollipop-->
|
||||
<!-- Adds nicer selector attributes not supported on lollipop -->
|
||||
<style name="Theme.Auxio.V23" parent="Theme.Auxio" />
|
||||
<!-- Handles edge-to-edge on other styles variants -->
|
||||
<style name="Theme.Auxio.V27" parent="Theme.Auxio.V23">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- SHARED RE-USABLE UI STYLES -->
|
||||
|
||||
<style name="Widget.Auxio.AppBarLayout" parent="Widget.Material3.AppBarLayout">
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
app:entryIcons="@array/icons_theme"
|
||||
app:entryValues="@array/values_theme"
|
||||
app:icon="@drawable/ic_light_24"
|
||||
app:isPreferenceVisible="@bool/enable_theme_settings"
|
||||
app:key="@string/set_key_theme"
|
||||
app:title="@string/set_theme" />
|
||||
|
||||
|
|
Loading…
Reference in a new issue