Refactor alert dialogs
parent
0df67b86f8
commit
5ebbfd1c00
@ -0,0 +1,67 @@
|
|||||||
|
package org.koitharu.kotatsu.core.ui.dialog
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.widget.CompoundButton.OnCheckedChangeListener
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.core.view.updatePadding
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.AdapterDelegate
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.AdapterDelegatesManager
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.ListDelegationAdapter
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.databinding.DialogCheckboxBinding
|
||||||
|
import com.google.android.material.R as materialR
|
||||||
|
|
||||||
|
inline fun buildAlertDialog(
|
||||||
|
context: Context,
|
||||||
|
isCentered: Boolean = false,
|
||||||
|
block: MaterialAlertDialogBuilder.() -> Unit,
|
||||||
|
): AlertDialog = MaterialAlertDialogBuilder(
|
||||||
|
context,
|
||||||
|
if (isCentered) materialR.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered else 0,
|
||||||
|
).apply(block).create()
|
||||||
|
|
||||||
|
fun <B : AlertDialog.Builder> B.setCheckbox(
|
||||||
|
@StringRes textResId: Int,
|
||||||
|
isChecked: Boolean,
|
||||||
|
onCheckedChangeListener: OnCheckedChangeListener
|
||||||
|
) = apply {
|
||||||
|
val binding = DialogCheckboxBinding.inflate(LayoutInflater.from(context))
|
||||||
|
binding.checkbox.setText(textResId)
|
||||||
|
binding.checkbox.isChecked = isChecked
|
||||||
|
binding.checkbox.setOnCheckedChangeListener(onCheckedChangeListener)
|
||||||
|
setView(binding.root)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <B : AlertDialog.Builder, T> B.setRecyclerViewList(
|
||||||
|
list: List<T>,
|
||||||
|
delegate: AdapterDelegate<List<T>>,
|
||||||
|
) = apply {
|
||||||
|
val delegatesManager = AdapterDelegatesManager<List<T>>()
|
||||||
|
delegatesManager.addDelegate(delegate)
|
||||||
|
setRecyclerViewList(ListDelegationAdapter(delegatesManager).also { it.items = list })
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <B : AlertDialog.Builder, T> B.setRecyclerViewList(
|
||||||
|
list: List<T>,
|
||||||
|
vararg delegates: AdapterDelegate<List<T>>,
|
||||||
|
) = apply {
|
||||||
|
val delegatesManager = AdapterDelegatesManager<List<T>>()
|
||||||
|
delegates.forEach { delegatesManager.addDelegate(it) }
|
||||||
|
setRecyclerViewList(ListDelegationAdapter(delegatesManager).also { it.items = list })
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <B : AlertDialog.Builder> B.setRecyclerViewList(adapter: RecyclerView.Adapter<*>) = apply {
|
||||||
|
val recyclerView = RecyclerView(context)
|
||||||
|
recyclerView.layoutManager = LinearLayoutManager(context)
|
||||||
|
recyclerView.updatePadding(
|
||||||
|
top = context.resources.getDimensionPixelOffset(R.dimen.list_spacing),
|
||||||
|
)
|
||||||
|
recyclerView.clipToPadding = false
|
||||||
|
recyclerView.adapter = adapter
|
||||||
|
setView(recyclerView)
|
||||||
|
}
|
||||||
@ -1,80 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.core.ui.dialog
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.DialogInterface
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import androidx.annotation.DrawableRes
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import org.koitharu.kotatsu.databinding.DialogCheckboxBinding
|
|
||||||
|
|
||||||
class CheckBoxAlertDialog private constructor(private val delegate: AlertDialog) :
|
|
||||||
DialogInterface by delegate {
|
|
||||||
|
|
||||||
fun show() = delegate.show()
|
|
||||||
|
|
||||||
class Builder(context: Context) {
|
|
||||||
|
|
||||||
private val binding = DialogCheckboxBinding.inflate(LayoutInflater.from(context))
|
|
||||||
|
|
||||||
private val delegate = MaterialAlertDialogBuilder(context)
|
|
||||||
.setView(binding.root)
|
|
||||||
|
|
||||||
fun setTitle(@StringRes titleResId: Int): Builder {
|
|
||||||
delegate.setTitle(titleResId)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setTitle(title: CharSequence): Builder {
|
|
||||||
delegate.setTitle(title)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setMessage(@StringRes messageId: Int): Builder {
|
|
||||||
delegate.setMessage(messageId)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setMessage(message: CharSequence): Builder {
|
|
||||||
delegate.setMessage(message)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setCheckBoxText(@StringRes textId: Int): Builder {
|
|
||||||
binding.checkbox.setText(textId)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setCheckBoxChecked(isChecked: Boolean): Builder {
|
|
||||||
binding.checkbox.isChecked = isChecked
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setIcon(@DrawableRes iconId: Int): Builder {
|
|
||||||
delegate.setIcon(iconId)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setPositiveButton(
|
|
||||||
@StringRes textId: Int,
|
|
||||||
listener: (DialogInterface, Boolean) -> Unit
|
|
||||||
): Builder {
|
|
||||||
delegate.setPositiveButton(textId) { dialog, _ ->
|
|
||||||
listener(dialog, binding.checkbox.isChecked)
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setNegativeButton(
|
|
||||||
@StringRes textId: Int,
|
|
||||||
listener: DialogInterface.OnClickListener? = null
|
|
||||||
): Builder {
|
|
||||||
delegate.setNegativeButton(textId, listener)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun create() = CheckBoxAlertDialog(delegate.create())
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,101 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.core.ui.dialog
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.DialogInterface
|
|
||||||
import androidx.annotation.DrawableRes
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.core.view.updatePadding
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import com.hannesdorfmann.adapterdelegates4.AdapterDelegate
|
|
||||||
import com.hannesdorfmann.adapterdelegates4.AdapterDelegatesManager
|
|
||||||
import com.hannesdorfmann.adapterdelegates4.ListDelegationAdapter
|
|
||||||
import org.koitharu.kotatsu.R
|
|
||||||
|
|
||||||
class RecyclerViewAlertDialog private constructor(
|
|
||||||
private val delegate: AlertDialog
|
|
||||||
) : DialogInterface by delegate {
|
|
||||||
|
|
||||||
fun show() = delegate.show()
|
|
||||||
|
|
||||||
class Builder<T>(context: Context) {
|
|
||||||
|
|
||||||
private val recyclerView = RecyclerView(context)
|
|
||||||
private val delegatesManager = AdapterDelegatesManager<List<T>>()
|
|
||||||
private var items: List<T>? = null
|
|
||||||
|
|
||||||
private val delegate = MaterialAlertDialogBuilder(context)
|
|
||||||
.setView(recyclerView)
|
|
||||||
|
|
||||||
init {
|
|
||||||
recyclerView.layoutManager = LinearLayoutManager(context)
|
|
||||||
recyclerView.updatePadding(
|
|
||||||
top = context.resources.getDimensionPixelOffset(R.dimen.list_spacing),
|
|
||||||
)
|
|
||||||
recyclerView.clipToPadding = false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setTitle(@StringRes titleResId: Int): Builder<T> {
|
|
||||||
delegate.setTitle(titleResId)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setTitle(title: CharSequence): Builder<T> {
|
|
||||||
delegate.setTitle(title)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setIcon(@DrawableRes iconId: Int): Builder<T> {
|
|
||||||
delegate.setIcon(iconId)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setPositiveButton(
|
|
||||||
@StringRes textId: Int,
|
|
||||||
listener: DialogInterface.OnClickListener,
|
|
||||||
): Builder<T> {
|
|
||||||
delegate.setPositiveButton(textId, listener)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setNegativeButton(
|
|
||||||
@StringRes textId: Int,
|
|
||||||
listener: DialogInterface.OnClickListener? = null
|
|
||||||
): Builder<T> {
|
|
||||||
delegate.setNegativeButton(textId, listener)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setNeutralButton(
|
|
||||||
@StringRes textId: Int,
|
|
||||||
listener: DialogInterface.OnClickListener,
|
|
||||||
): Builder<T> {
|
|
||||||
delegate.setNeutralButton(textId, listener)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setCancelable(isCancelable: Boolean): Builder<T> {
|
|
||||||
delegate.setCancelable(isCancelable)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addAdapterDelegate(subject: AdapterDelegate<List<T>>): Builder<T> {
|
|
||||||
delegatesManager.addDelegate(subject)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setItems(list: List<T>): Builder<T> {
|
|
||||||
items = list
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun create(): RecyclerViewAlertDialog {
|
|
||||||
recyclerView.adapter = ListDelegationAdapter(delegatesManager).also {
|
|
||||||
it.items = items
|
|
||||||
}
|
|
||||||
return RecyclerViewAlertDialog(delegate.create())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package org.koitharu.kotatsu.core.ui.dialog
|
||||||
|
|
||||||
|
import android.widget.CompoundButton
|
||||||
|
import android.widget.CompoundButton.OnCheckedChangeListener
|
||||||
|
|
||||||
|
class RememberCheckListener(
|
||||||
|
initialValue: Boolean,
|
||||||
|
) : OnCheckedChangeListener {
|
||||||
|
|
||||||
|
var isChecked: Boolean = initialValue
|
||||||
|
private set
|
||||||
|
|
||||||
|
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
|
||||||
|
this.isChecked = isChecked
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?colorControlNormal"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:pathData="M15,16H19V18H15V16M15,8H22V10H15V8M15,12H21V14H15V12M11,10V18H5V10H11M13,8H3V18A2,2 0 0,0 5,20H11A2,2 0 0,0 13,18V8M14,5H11L10,4H6L5,5H2V7H14V5Z" />
|
||||||
|
</vector>
|
||||||
Loading…
Reference in New Issue