Simplify checkbox access in PreferenceView

Add widget and checkbox properties to PreferenceView, eliminating
repetitive findViewById<QkSwitch>(R.id.checkbox) calls throughout
the codebase.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Ben Iofel
2026-01-12 02:06:18 -05:00
parent 7f984f715e
commit 6f3d6cc679
6 changed files with 30 additions and 32 deletions
@@ -40,6 +40,12 @@ class PreferenceView @JvmOverloads constructor(
val titleView: TextView get() = layout.titleView
/** Returns the widget view inflated into the widget frame, if any */
val widget: View? get() = layout.widgetFrame.getChildAt(0)
/** Returns the checkbox widget if this preference has one */
val checkbox: QkSwitch? get() = widget as? QkSwitch
var title: String? = null
set(value) {
field = value
@@ -34,7 +34,6 @@ import dev.octoshrimpy.quik.feature.blocking.numbers.BlockedNumbersController
import dev.octoshrimpy.quik.feature.blocking.filters.MessageContentFiltersController
import dev.octoshrimpy.quik.injection.appComponent
import dev.octoshrimpy.quik.databinding.BlockingControllerBinding
import dev.octoshrimpy.quik.common.widget.QkSwitch
import javax.inject.Inject
class BlockingController : QkController<BlockingControllerBinding, BlockingView, BlockingState, BlockingPresenter>(), BlockingView {
@@ -70,7 +69,7 @@ class BlockingController : QkController<BlockingControllerBinding, BlockingView,
override fun render(state: BlockingState) {
binding.blockingManager.summary = state.blockingManager
binding.drop.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.dropEnabled
binding.drop.checkbox?.isChecked = state.dropEnabled
binding.blockedMessages.isEnabled = !state.dropEnabled
}
@@ -34,7 +34,6 @@ import dev.octoshrimpy.quik.injection.appComponent
import dev.octoshrimpy.quik.model.MessageContentFilterData
import dev.octoshrimpy.quik.databinding.MessageContentFiltersControllerBinding
import dev.octoshrimpy.quik.databinding.MessageContentFiltersAddDialogBinding
import dev.octoshrimpy.quik.common.widget.QkSwitch
import io.reactivex.Observable
import io.reactivex.subjects.PublishSubject
import io.reactivex.subjects.Subject
@@ -90,9 +89,8 @@ class MessageContentFiltersController : QkController<MessageContentFiltersContro
.let { Observable.merge(it) }
.autoDisposable(scope())
.subscribe { pref ->
val checkbox = pref.findViewById<QkSwitch>(R.id.checkbox)
checkbox?.isChecked = !(checkbox?.isChecked ?: false)
val regexChecked = layout.regexp.findViewById<QkSwitch>(R.id.checkbox)?.isChecked ?: false
pref.checkbox?.let { it.isChecked = !it.isChecked }
val regexChecked = layout.regexp.checkbox?.isChecked ?: false
layout.caseSensitivity.isEnabled = !regexChecked
}
@@ -101,14 +99,14 @@ class MessageContentFiltersController : QkController<MessageContentFiltersContro
.setPositiveButton(R.string.message_content_filters_dialog_create) { _, _ ->
var text = layout.input.text.toString();
if (!text.isBlank()) {
val regexChecked = layout.regexp.findViewById<QkSwitch>(R.id.checkbox)?.isChecked ?: false
val regexChecked = layout.regexp.checkbox?.isChecked ?: false
if (!regexChecked) text = text.trim()
saveFilterSubject.onNext(
MessageContentFilterData(
text,
(layout.caseSensitivity.findViewById<QkSwitch>(R.id.checkbox)?.isChecked == true) && !regexChecked,
(layout.caseSensitivity.checkbox?.isChecked == true) && !regexChecked,
regexChecked,
layout.contacts.findViewById<QkSwitch>(R.id.checkbox)?.isChecked == true
layout.contacts.checkbox?.isChecked == true
)
)
}
@@ -10,7 +10,6 @@ import com.jakewharton.rxbinding2.view.clicks
import dev.octoshrimpy.quik.R
import dev.octoshrimpy.quik.common.base.QkController
import dev.octoshrimpy.quik.common.util.extensions.animateLayoutChanges
import dev.octoshrimpy.quik.common.widget.QkSwitch
import dev.octoshrimpy.quik.databinding.MessageUtilsControllerBinding
import dev.octoshrimpy.quik.injection.appComponent
import dev.octoshrimpy.quik.repository.MessageRepository
@@ -46,9 +45,7 @@ class MessageUtilsController : QkController<MessageUtilsControllerBinding, Messa
}
override fun render(state: MessageUtilsState) {
binding.autoDeduplicate
.findViewById<QkSwitch>(R.id.checkbox)
?.isChecked = state.autoDeduplicateMessages
binding.autoDeduplicate.checkbox?.isChecked = state.autoDeduplicateMessages
val deduplicationProgress = binding.deduplicationProgress
val progressAnimator = ObjectAnimator.ofInt(deduplicationProgress, "progress", 0, 0)
@@ -37,7 +37,6 @@ import dev.octoshrimpy.quik.common.base.QkThemedActivity
import dev.octoshrimpy.quik.common.util.extensions.animateLayoutChanges
import dev.octoshrimpy.quik.common.util.extensions.setVisible
import dev.octoshrimpy.quik.common.widget.PreferenceView
import dev.octoshrimpy.quik.common.widget.QkSwitch
import dev.octoshrimpy.quik.databinding.NotificationPrefsActivityBinding
import io.reactivex.Observable
import io.reactivex.subjects.PublishSubject
@@ -98,13 +97,13 @@ class NotificationPrefsActivity : QkThemedActivity(), NotificationPrefsView {
title = state.conversationTitle
}
binding.notifications.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.notificationsEnabled
binding.notifications.checkbox?.isChecked = state.notificationsEnabled
binding.previews.summary = state.previewSummary
previewModeDialog.adapter.selectedItem = state.previewId
binding.wake.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.wakeEnabled
binding.silentNotContact.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.silentNotContact
binding.wake.checkbox?.isChecked = state.wakeEnabled
binding.silentNotContact.checkbox?.isChecked = state.silentNotContact
binding.silentNotContact.isVisible = state.threadId == 0L
binding.vibration.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.vibrationEnabled
binding.vibration.checkbox?.isChecked = state.vibrationEnabled
binding.ringtone.summary = state.ringtoneName
binding.actionsDivider.isVisible = state.threadId == 0L
@@ -118,11 +117,11 @@ class NotificationPrefsActivity : QkThemedActivity(), NotificationPrefsView {
binding.qkreplyDivider.isVisible = state.threadId == 0L
binding.qkreplyTitle.isVisible = state.threadId == 0L
binding.qkreply.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.qkReplyEnabled
binding.qkreply.checkbox?.isChecked = state.qkReplyEnabled
binding.qkreply.isVisible = state.threadId == 0L
binding.qkreplyTapDismiss.isVisible = state.threadId == 0L
binding.qkreplyTapDismiss.isEnabled = state.qkReplyEnabled
binding.qkreplyTapDismiss.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.qkReplyTapDismiss
binding.qkreplyTapDismiss.checkbox?.isChecked = state.qkReplyTapDismiss
}
override fun showPreviewModeDialog() = previewModeDialog.show(this)
@@ -45,7 +45,6 @@ import dev.octoshrimpy.quik.common.util.extensions.animateLayoutChanges
import dev.octoshrimpy.quik.common.util.extensions.setBackgroundTint
import dev.octoshrimpy.quik.common.util.extensions.setVisible
import dev.octoshrimpy.quik.common.widget.PreferenceView
import dev.octoshrimpy.quik.common.widget.QkSwitch
import dev.octoshrimpy.quik.common.widget.TextInputDialog
import dev.octoshrimpy.quik.databinding.SettingsControllerBinding
import dev.octoshrimpy.quik.feature.settings.about.AboutController
@@ -165,16 +164,16 @@ class SettingsController : QkController<SettingsControllerBinding, SettingsView,
binding.nightEnd.summary = state.nightEnd
binding.black.setVisible(state.nightModeId != Preferences.NIGHT_MODE_OFF)
binding.black.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.black
binding.black.checkbox?.isChecked = state.black
binding.autoEmoji.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.autoEmojiEnabled
binding.autoEmoji.checkbox?.isChecked = state.autoEmojiEnabled
binding.delayed.summary = state.sendDelaySummary
sendDelayDialog.adapter.selectedItem = state.sendDelayId
binding.delivery.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.deliveryEnabled
binding.delivery.checkbox?.isChecked = state.deliveryEnabled
binding.unreadAtTop.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.unreadAtTopEnabled
binding.unreadAtTop.checkbox?.isChecked = state.unreadAtTopEnabled
binding.signature.summary = state.signature.takeIf { it.isNotBlank() }
?: context.getString(R.string.settings_signature_summary)
@@ -182,14 +181,14 @@ class SettingsController : QkController<SettingsControllerBinding, SettingsView,
binding.textSize.summary = state.textSizeSummary
textSizeDialog.adapter.selectedItem = state.textSizeId
binding.autoColor.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.autoColor
binding.autoColor.checkbox?.isChecked = state.autoColor
binding.systemFont.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.systemFontEnabled
binding.systemFont.checkbox?.isChecked = state.systemFontEnabled
binding.showStt.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.showStt
binding.showStt.checkbox?.isChecked = state.showStt
binding.unicode.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.stripUnicodeEnabled
binding.mobileOnly.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.mobileOnly
binding.unicode.checkbox?.isChecked = state.stripUnicodeEnabled
binding.mobileOnly.checkbox?.isChecked = state.mobileOnly
binding.autoDelete.summary = when (state.autoDelete) {
0 -> context.getString(R.string.settings_auto_delete_never)
@@ -197,7 +196,7 @@ class SettingsController : QkController<SettingsControllerBinding, SettingsView,
R.plurals.settings_auto_delete_summary, state.autoDelete, state.autoDelete)
}
binding.longAsMms.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.longAsMms
binding.longAsMms.checkbox?.isChecked = state.longAsMms
binding.mmsSize.summary = state.maxMmsSizeSummary
mmsSizeDialog.adapter.selectedItem = state.maxMmsSizeId
@@ -205,7 +204,7 @@ class SettingsController : QkController<SettingsControllerBinding, SettingsView,
binding.messsageLinkHandling.summary = state.messageLinkHandlingSummary
messageLinkHandlingDialog.adapter.selectedItem = state.messageLinkHandlingId
binding.disableScreenshots.findViewById<QkSwitch>(R.id.checkbox)?.isChecked = state.disableScreenshotsEnabled
binding.disableScreenshots.checkbox?.isChecked = state.disableScreenshotsEnabled
when (state.syncProgress) {
is SyncRepository.SyncProgress.Idle -> binding.syncingProgress.isVisible = false