Migrate to MaterialDividerItemDecoration

This commit is contained in:
Koitharu
2022-02-03 08:47:51 +02:00
parent add72c0be3
commit 4be514b754
11 changed files with 63 additions and 112 deletions

View File

@@ -1,18 +1,39 @@
package org.koitharu.kotatsu.base.ui.list.decor package org.koitharu.kotatsu.base.ui.list.decor
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect import android.graphics.Rect
import android.view.View import android.view.View
import androidx.core.content.res.getColorOrThrow
import androidx.core.view.children import androidx.core.view.children
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.koitharu.kotatsu.utils.ext.getThemeDrawable import com.google.android.material.R as materialR
import kotlin.math.roundToInt
@SuppressLint("PrivateResource")
abstract class AbstractDividerItemDecoration(context: Context) : RecyclerView.ItemDecoration() { abstract class AbstractDividerItemDecoration(context: Context) : RecyclerView.ItemDecoration() {
private val bounds = Rect() private val bounds = Rect()
private val divider = context.getThemeDrawable(android.R.attr.listDivider) private val thickness: Int
private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
init {
paint.style = Paint.Style.FILL
val ta = context.obtainStyledAttributes(
null,
materialR.styleable.MaterialDivider,
materialR.attr.materialDividerStyle,
materialR.style.Widget_Material3_MaterialDivider,
)
paint.color = ta.getColorOrThrow(materialR.styleable.MaterialDivider_dividerColor)
thickness = ta.getDimensionPixelSize(
materialR.styleable.MaterialDivider_dividerThickness,
context.resources.getDimensionPixelSize(materialR.dimen.material_divider_thickness),
)
ta.recycle()
}
override fun getItemOffsets( override fun getItemOffsets(
outRect: Rect, outRect: Rect,
@@ -20,27 +41,29 @@ abstract class AbstractDividerItemDecoration(context: Context) : RecyclerView.It
parent: RecyclerView, parent: RecyclerView,
state: RecyclerView.State, state: RecyclerView.State,
) { ) {
outRect.set(0, divider?.intrinsicHeight ?: 0, 0, 0) outRect.set(0, thickness, 0, 0)
} }
// TODO implement for horizontal lists on demand // TODO implement for horizontal lists on demand
override fun onDraw(canvas: Canvas, parent: RecyclerView, s: RecyclerView.State) { override fun onDraw(canvas: Canvas, parent: RecyclerView, s: RecyclerView.State) {
if (parent.layoutManager == null || divider == null) { if (parent.layoutManager == null || thickness == 0) {
return return
} }
canvas.save() canvas.save()
val left: Int val left: Float
val right: Int val right: Float
if (parent.clipToPadding) { if (parent.clipToPadding) {
left = parent.paddingLeft left = parent.paddingLeft.toFloat()
right = parent.width - parent.paddingRight right = (parent.width - parent.paddingRight).toFloat()
canvas.clipRect( canvas.clipRect(
left, parent.paddingTop, right, left,
parent.height - parent.paddingBottom parent.paddingTop.toFloat(),
right,
(parent.height - parent.paddingBottom).toFloat()
) )
} else { } else {
left = 0 left = 0f
right = parent.width right = parent.width.toFloat()
} }
var previous: RecyclerView.ViewHolder? = null var previous: RecyclerView.ViewHolder? = null
@@ -48,10 +71,9 @@ abstract class AbstractDividerItemDecoration(context: Context) : RecyclerView.It
val holder = parent.getChildViewHolder(child) val holder = parent.getChildViewHolder(child)
if (previous != null && shouldDrawDivider(previous, holder)) { if (previous != null && shouldDrawDivider(previous, holder)) {
parent.getDecoratedBoundsWithMargins(child, bounds) parent.getDecoratedBoundsWithMargins(child, bounds)
val top: Int = bounds.top + child.translationY.roundToInt() val top: Float = bounds.top + child.translationY
val bottom: Int = top + divider.intrinsicHeight val bottom: Float = top + thickness
divider.setBounds(left, top, right, bottom) canvas.drawRect(left, top, right, bottom, paint)
divider.draw(canvas)
} }
previous = holder previous = holder
} }

View File

@@ -1,58 +0,0 @@
package org.koitharu.kotatsu.base.ui.list.decor
import android.content.Context
import android.graphics.Canvas
import android.graphics.Rect
import android.view.View
import androidx.core.view.children
import androidx.recyclerview.widget.RecyclerView
import org.koitharu.kotatsu.utils.ext.getThemeDrawable
import kotlin.math.roundToInt
class ItemTypeDividerDecoration(context: Context) : RecyclerView.ItemDecoration() {
private val divider = context.getThemeDrawable(android.R.attr.listDivider)
private val bounds = Rect()
override fun getItemOffsets(
outRect: Rect, view: View,
parent: RecyclerView, state: RecyclerView.State
) {
outRect.set(0, divider?.intrinsicHeight ?: 0, 0, 0)
}
override fun onDraw(canvas: Canvas, parent: RecyclerView, s: RecyclerView.State) {
if (parent.layoutManager == null || divider == null) {
return
}
val adapter = parent.adapter ?: return
canvas.save()
val left: Int
val right: Int
if (parent.clipToPadding) {
left = parent.paddingLeft
right = parent.width - parent.paddingRight
canvas.clipRect(
left, parent.paddingTop, right,
parent.height - parent.paddingBottom
)
} else {
left = 0
right = parent.width
}
var lastItemType = -1
for (child in parent.children) {
val itemType = adapter.getItemViewType(parent.getChildAdapterPosition(child))
if (lastItemType != -1 && itemType != lastItemType) {
parent.getDecoratedBoundsWithMargins(child, bounds)
val top: Int = bounds.top + child.translationY.roundToInt()
val bottom: Int = top + divider.intrinsicHeight
divider.setBounds(left, top, right, bottom)
divider.draw(canvas)
}
lastItemType = itemType
}
canvas.restore()
}
}

View File

@@ -2,11 +2,13 @@ package org.koitharu.kotatsu.core.prefs
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Build
import android.provider.Settings import android.provider.Settings
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.collection.arraySetOf import androidx.collection.arraySetOf
import androidx.core.content.edit import androidx.core.content.edit
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.google.android.material.color.DynamicColors
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.trySendBlocking import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.callbackFlow
@@ -210,5 +212,12 @@ class AppSettings private constructor(private val prefs: SharedPreferences) :
const val KEY_FEEDBACK_4PDA = "about_feedback_4pda" const val KEY_FEEDBACK_4PDA = "about_feedback_4pda"
const val KEY_FEEDBACK_GITHUB = "about_feedback_github" const val KEY_FEEDBACK_GITHUB = "about_feedback_github"
const val KEY_SUPPORT_DEVELOPER = "about_support_developer" const val KEY_SUPPORT_DEVELOPER = "about_support_developer"
val isDynamicColorAvailable: Boolean
get() = DynamicColors.isDynamicColorAvailable() ||
(isSamsung && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
private val isSamsung
get() = Build.MANUFACTURER.equals("samsung", ignoreCase = true)
} }
} }

View File

@@ -2,8 +2,6 @@ package org.koitharu.kotatsu.favourites.ui.categories
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.View import android.view.View
@@ -12,9 +10,9 @@ import androidx.core.graphics.Insets
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.divider.MaterialDividerItemDecoration
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@@ -43,7 +41,7 @@ class CategoriesActivity : BaseActivity<ActivityCategoriesBinding>(),
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
adapter = CategoriesAdapter(this) adapter = CategoriesAdapter(this)
editDelegate = CategoriesEditDelegate(this, this) editDelegate = CategoriesEditDelegate(this, this)
binding.recyclerView.addItemDecoration(DividerItemDecoration(this, RecyclerView.VERTICAL)) binding.recyclerView.addItemDecoration(MaterialDividerItemDecoration(this, RecyclerView.VERTICAL))
binding.recyclerView.setHasFixedSize(true) binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.adapter = adapter binding.recyclerView.adapter = adapter
binding.fabAdd.setOnClickListener(this) binding.fabAdd.setOnClickListener(this)

View File

@@ -5,10 +5,10 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.divider.MaterialDividerItemDecoration
import org.koin.android.ext.android.get import org.koin.android.ext.android.get
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.AlertDialogFragment import org.koitharu.kotatsu.base.ui.AlertDialogFragment
@@ -37,7 +37,7 @@ class ChaptersDialog : AlertDialogFragment<DialogChaptersBinding>(),
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding.recyclerViewChapters.addItemDecoration( binding.recyclerViewChapters.addItemDecoration(
DividerItemDecoration(requireContext(), RecyclerView.VERTICAL) MaterialDividerItemDecoration(view.context, RecyclerView.VERTICAL)
) )
val chapters = arguments?.getParcelableArrayList<MangaChapter>(ARG_CHAPTERS) val chapters = arguments?.getParcelableArrayList<MangaChapter>(ARG_CHAPTERS)
if (chapters == null) { if (chapters == null) {

View File

@@ -13,7 +13,6 @@ import org.koitharu.kotatsu.core.model.MangaSource
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.prefs.ListMode import org.koitharu.kotatsu.core.prefs.ListMode
import org.koitharu.kotatsu.settings.protect.ProtectSetupActivity import org.koitharu.kotatsu.settings.protect.ProtectSetupActivity
import org.koitharu.kotatsu.utils.DeviceUtil
import org.koitharu.kotatsu.utils.ext.getStorageName import org.koitharu.kotatsu.utils.ext.getStorageName
import org.koitharu.kotatsu.utils.ext.names import org.koitharu.kotatsu.utils.ext.names
import org.koitharu.kotatsu.utils.ext.setDefaultValueCompat import org.koitharu.kotatsu.utils.ext.setDefaultValueCompat
@@ -39,7 +38,7 @@ class MainSettingsFragment : BasePreferenceFragment(R.string.settings),
setDefaultValueCompat(ListMode.GRID.name) setDefaultValueCompat(ListMode.GRID.name)
} }
findPreference<SwitchPreference>(AppSettings.KEY_DYNAMIC_THEME)?.isVisible = findPreference<SwitchPreference>(AppSettings.KEY_DYNAMIC_THEME)?.isVisible =
DeviceUtil.isDynamicColorAvailable AppSettings.isDynamicColorAvailable
findPreference<ListPreference>(AppSettings.KEY_DATE_FORMAT)?.run { findPreference<ListPreference>(AppSettings.KEY_DATE_FORMAT)?.run {
entryValues = arrayOf("", "MM/dd/yy", "dd/MM/yy", "yyyy-MM-dd", "dd MMM yyyy", "MMM dd, yyyy") entryValues = arrayOf("", "MM/dd/yy", "dd/MM/yy", "yyyy-MM-dd", "dd MMM yyyy", "MMM dd, yyyy")
val now = Date().time val now = Date().time

View File

@@ -1,16 +0,0 @@
package org.koitharu.kotatsu.utils
import android.os.Build
import com.google.android.material.color.DynamicColors
object DeviceUtil {
private val isSamsung by lazy {
Build.MANUFACTURER.equals("samsung", ignoreCase = true)
}
val isDynamicColorAvailable by lazy {
DynamicColors.isDynamicColorAvailable() || (isSamsung && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
}
}

View File

@@ -4,6 +4,7 @@ import android.content.Context
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.Network import android.net.Network
import android.net.NetworkRequest import android.net.NetworkRequest
import android.os.Build
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine

View File

@@ -3,19 +3,16 @@ package org.koitharu.kotatsu.widget.shelf
import android.app.Activity import android.app.Activity
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.content.Intent import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.graphics.Insets import androidx.core.graphics.Insets
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.divider.MaterialDividerItemDecoration
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@@ -40,7 +37,9 @@ class ShelfConfigActivity : BaseActivity<ActivityCategoriesBinding>(),
setContentView(ActivityCategoriesBinding.inflate(layoutInflater)) setContentView(ActivityCategoriesBinding.inflate(layoutInflater))
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
adapter = CategorySelectAdapter(this) adapter = CategorySelectAdapter(this)
binding.recyclerView.addItemDecoration(DividerItemDecoration(this, RecyclerView.VERTICAL)) binding.recyclerView.addItemDecoration(
MaterialDividerItemDecoration(this, RecyclerView.VERTICAL)
)
binding.recyclerView.adapter = adapter binding.recyclerView.adapter = adapter
binding.fabAdd.hide() binding.fabAdd.hide()
val appWidgetId = intent?.getIntExtra( val appWidgetId = intent?.getIntExtra(

View File

@@ -14,10 +14,9 @@
android:padding="16dp" android:padding="16dp"
android:text="@string/add_to_favourites" /> android:text="@string/add_to_favourites" />
<View <com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="wrap_content" />
android:background="?attr/colorOutline" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView_categories" android:id="@+id/recyclerView_categories"
@@ -29,10 +28,9 @@
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_category_checkable" /> tools:listitem="@layout/item_category_checkable" />
<View <com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="wrap_content" />
android:background="?attr/colorOutline" />
<TextView <TextView
android:id="@+id/textView_add" android:id="@+id/textView_add"

View File

@@ -38,7 +38,6 @@
android:layout_below="@id/imageView_logo" android:layout_below="@id/imageView_logo"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_marginHorizontal="28dp" android:layout_marginHorizontal="28dp" />
android:background="?attr/colorOutline" />
</RelativeLayout> </RelativeLayout>