From 2e788e62e23b100dd2e346d42975261a12b5321a Mon Sep 17 00:00:00 2001 From: David Allison <62114487+david-allison@users.noreply.github.com> Date: Sat, 27 Aug 2022 16:16:31 +0100 Subject: [PATCH] NF: Kotlin Cleanup (#12192) * refactor: Kotlin Cleanup: CardTemplateEditor * lint: fix typo 'lukstbit' * refactor: Kotlin Cleanup: CardTemplateEditor --- .idea/dictionaries/usernames.xml | 1 + .../java/com/ichi2/anki/CardTemplateEditor.kt | 284 ++++++++---------- .../dialogs/CardBrowserMySearchesDialog.kt | 30 +- .../java/com/ichi2/ui/ButtonItemAdapter.kt | 65 ++-- 4 files changed, 168 insertions(+), 212 deletions(-) diff --git a/.idea/dictionaries/usernames.xml b/.idea/dictionaries/usernames.xml index 61d5e900f6..add536659e 100644 --- a/.idea/dictionaries/usernames.xml +++ b/.idea/dictionaries/usernames.xml @@ -64,6 +64,7 @@ Woitaschek bresan joshakaw + lukstbit mikunimaru msync pablomouzo diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateEditor.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateEditor.kt index 0f457134eb..4a38e84b2c 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateEditor.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateEditor.kt @@ -59,11 +59,12 @@ import com.ichi2.ui.FixedTextView import com.ichi2.utils.* import timber.log.Timber import java.util.regex.Pattern +import kotlin.math.max +import kotlin.math.min /** * Allows the user to view the template for the current note type */ -@KotlinCleanup("IDE-lint") @KotlinCleanup("lateinit wherever possible") open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { @VisibleForTesting @@ -76,10 +77,10 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { private var mNoteId: NoteId = 0 // the position of the cursor in the editor view - private var tabToCursorPosition: HashMap? = null + private var tabToCursorPosition: HashMap = HashMap() // the current editor view among front/style/back - private var tabToViewId: HashMap? = null + private var tabToViewId: HashMap = HashMap() private var mStartingOrdId = 0 // ---------------------------------------------------------------------------- @@ -98,8 +99,6 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { super.onCreate(savedInstanceState) setContentView(R.layout.card_template_editor_activity) // Load the args either from the intent or savedInstanceState bundle - tabToCursorPosition = HashMap() - tabToViewId = HashMap() if (savedInstanceState == null) { // get model id mModelId = intent.getLongExtra(EDITOR_MODEL_ID, NOT_FOUND_NOTE_TYPE) @@ -112,31 +111,34 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { mNoteId = intent.getLongExtra(EDITOR_NOTE_ID, -1L) // get id for currently edited template (optional) mStartingOrdId = intent.getIntExtra("ordId", -1) - tabToCursorPosition!![0] = 0 - tabToViewId!![0] = R.id.front_edit + tabToCursorPosition[0] = 0 + tabToViewId[0] = R.id.front_edit } else { mModelId = savedInstanceState.getLong(EDITOR_MODEL_ID) mNoteId = savedInstanceState.getLong(EDITOR_NOTE_ID) mStartingOrdId = savedInstanceState.getInt(EDITOR_START_ORD_ID) - tabToCursorPosition = savedInstanceState.getSerializable(TAB_TO_CURSOR_POSITION_KEY) as HashMap? - tabToViewId = savedInstanceState.getSerializable(TAB_TO_VIEW_ID) as HashMap? + tabToCursorPosition = savedInstanceState.getSerializable(TAB_TO_CURSOR_POSITION_KEY) as HashMap + tabToViewId = savedInstanceState.getSerializable(TAB_TO_VIEW_ID) as HashMap tempModel = TemporaryModel.fromBundle(savedInstanceState) } + mSlidingTabLayout = findViewById(R.id.sliding_tabs) + // Disable the home icon enableToolbar() startLoadingCollection() } - @KotlinCleanup("Scope function") public override fun onSaveInstanceState(outState: Bundle) { - outState.putAll(tempModel!!.toBundle()) - outState.putLong(EDITOR_MODEL_ID, mModelId) - outState.putLong(EDITOR_NOTE_ID, mNoteId) - outState.putInt(EDITOR_START_ORD_ID, mStartingOrdId) - outState.putSerializable(TAB_TO_VIEW_ID, tabToViewId) - outState.putSerializable(TAB_TO_CURSOR_POSITION_KEY, tabToCursorPosition) - super.onSaveInstanceState(outState) + with(outState) { + putAll(tempModel!!.toBundle()) + putLong(EDITOR_MODEL_ID, mModelId) + putLong(EDITOR_NOTE_ID, mNoteId) + putInt(EDITOR_START_ORD_ID, mStartingOrdId) + putSerializable(TAB_TO_VIEW_ID, tabToViewId) + putSerializable(TAB_TO_CURSOR_POSITION_KEY, tabToCursorPosition) + super.onSaveInstanceState(this) + } } override fun onBackPressed() { @@ -159,7 +161,6 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { * Callback used to finish initializing the activity after the collection has been correctly loaded * @param col Collection which has been loaded */ - @KotlinCleanup("Scope function") override fun onCollectionLoaded(col: Collection) { super.onCollectionLoaded(col) // The first time the activity loads it has a model id but no edits yet, so no edited model @@ -170,13 +171,13 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { } mFieldNames = tempModel!!.model.fieldsNames // Set up the ViewPager with the sections adapter. - viewPager = findViewById(R.id.pager) - viewPager.setAdapter(TemplatePagerAdapter(this)) - mSlidingTabLayout = findViewById(R.id.sliding_tabs) + viewPager = findViewById(R.id.pager).apply { + adapter = TemplatePagerAdapter(this@CardTemplateEditor) + } // Set activity title - if (supportActionBar != null) { - supportActionBar!!.setTitle(R.string.title_activity_template_editor) - supportActionBar!!.setSubtitle(tempModel!!.model.optString("name")) + supportActionBar?.let { + it.setTitle(R.string.title_activity_template_editor) + it.subtitle = tempModel!!.model.optString("name") } // Close collection opening dialog if needed Timber.i("CardTemplateEditor:: Card template editor successfully started for model id %d", mModelId) @@ -194,7 +195,6 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { } @VisibleForTesting - @KotlinCleanup("Remove type declarations after _") fun showDiscardChangesDialog(): MaterialDialog { val discardDialog = DiscardChangesDialog.showDialog(this) { Timber.i("TemplateEditor:: OK button pressed to confirm discard changes") @@ -270,30 +270,21 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { private var mBaseId: Long = 0 - @KotlinCleanup("Turn `editorPosition` and `editorViewId` into val") override fun createFragment(position: Int): Fragment { - var editorPosition = 0 - var editorViewId = R.id.front_edit - if (tabToCursorPosition!![position] != null && tabToViewId!![position] != null) { - editorPosition = tabToCursorPosition!![position]!! - editorViewId = tabToViewId!![position]!! - } + val editorPosition = tabToCursorPosition[position] ?: 0 + val editorViewId = tabToViewId[position] ?: R.id.front_edit return CardTemplateFragment.newInstance(position, mNoteId, editorPosition, editorViewId) } - @KotlinCleanup("Use ?:") - override fun getItemCount(): Int { - return if (tempModel != null) { - tempModel!!.templateCount - } else 0 - } + override fun getItemCount(): Int = tempModel?.templateCount ?: 0 override fun getItemId(position: Int): Long { return mBaseId + position } override fun containsItem(id: Long): Boolean { - return id - mBaseId < itemCount && id - mBaseId >= 0 + @Suppress("ConvertTwoComparisonsToRangeCheck") // more readable without the range check + return (id - mBaseId < itemCount) && (id - mBaseId >= 0) } /** Force fragments to reinitialize contents by invalidating previous set of ordinal-based ids */ @@ -337,14 +328,11 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { val bottomNavigation: BottomNavigationView = mainView.findViewById(R.id.card_template_editor_bottom_navigation) bottomNavigation.setOnItemSelectedListener { item: MenuItem -> val currentSelectedId = item.itemId - mTemplateEditor.tabToViewId!![cardIndex] = currentSelectedId - @KotlinCleanup("when") - if (currentSelectedId == R.id.styling_edit) { - setCurrentEditorView(currentSelectedId, tempModel.css, R.string.card_template_editor_styling) - } else if (currentSelectedId == R.id.back_edit) { - setCurrentEditorView(currentSelectedId, template.getString("afmt"), R.string.card_template_editor_back) - } else { - setCurrentEditorView(currentSelectedId, template.getString("qfmt"), R.string.card_template_editor_front) + mTemplateEditor.tabToViewId[cardIndex] = currentSelectedId + when (currentSelectedId) { + R.id.styling_edit -> setCurrentEditorView(currentSelectedId, tempModel.css, R.string.card_template_editor_styling) + R.id.back_edit -> setCurrentEditorView(currentSelectedId, template.getString("afmt"), R.string.card_template_editor_back) + else -> setCurrentEditorView(currentSelectedId, template.getString("qfmt"), R.string.card_template_editor_front) } // contents of menu have changed and menu should be redrawn mTemplateEditor.invalidateOptionsMenu() @@ -356,14 +344,11 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { // Set text change listeners val templateEditorWatcher: TextWatcher = object : TextWatcher { override fun afterTextChanged(arg0: Editable) { - mTemplateEditor.tabToCursorPosition!![cardIndex] = mEditorEditText.getSelectionStart() - @KotlinCleanup("when") - if (currentEditorViewId == R.id.styling_edit) { - tempModel.updateCss(mEditorEditText.getText().toString()) - } else if (currentEditorViewId == R.id.back_edit) { - template.put("afmt", mEditorEditText.getText()) - } else { - template.put("qfmt", mEditorEditText.getText()) + mTemplateEditor.tabToCursorPosition[cardIndex] = mEditorEditText.selectionStart + when (currentEditorViewId) { + R.id.styling_edit -> tempModel.updateCss(mEditorEditText.text.toString()) + R.id.back_edit -> template.put("afmt", mEditorEditText.text) + else -> template.put("qfmt", mEditorEditText.text) } mTemplateEditor.tempModel!!.updateTemplate(cardIndex, template) } @@ -435,11 +420,11 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { @Suppress("unused") private fun insertField(fieldName: String) { - val start = Math.max(mEditorEditText.selectionStart, 0) - val end = Math.max(mEditorEditText.selectionEnd, 0) + val start = max(mEditorEditText.selectionStart, 0) + val end = max(mEditorEditText.selectionEnd, 0) // add string to editText val updatedString = "{{$fieldName}}" - mEditorEditText.text!!.replace(Math.min(start, end), Math.max(start, end), updatedString, 0, updatedString.length) + mEditorEditText.text!!.replace(min(start, end), max(start, end), updatedString, 0, updatedString.length) } fun setCurrentEditorView(id: Int, editorContent: String, editorTitleId: Int) { @@ -471,11 +456,6 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { mTabLayoutMediator!!.attach() } - override fun onResume() { - // initTabLayoutMediator(); - super.onResume() - } - private fun setupMenu() { // Enable menu (requireActivity() as MenuHost).addMenuProvider( @@ -512,76 +492,80 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { override fun onMenuItemSelected(menuItem: MenuItem): Boolean { val col = mTemplateEditor.col val tempModel = mTemplateEditor.tempModel - val itemId = menuItem.itemId - @KotlinCleanup("when") - if (itemId == R.id.action_add) { - Timber.i("CardTemplateEditor:: Add template button pressed") - // Show confirmation dialog - val ordinal = mTemplateEditor.viewPager.currentItem - // isOrdinalPendingAdd method will check if there are any new card types added or not, - // if TempModel has new card type then numAffectedCards will be 0 by default. - val numAffectedCards = if (!TemporaryModel.isOrdinalPendingAdd(tempModel!!, ordinal)) { - col.models.tmplUseCount(tempModel.model, ordinal) - } else { - 0 - } - confirmAddCards(tempModel.model, numAffectedCards) - return true - } else if (itemId == R.id.action_insert_field) { - showInsertFieldDialog() - } else if (itemId == R.id.action_delete) { - Timber.i("CardTemplateEditor:: Delete template button pressed") - val res = resources - val ordinal = mTemplateEditor.viewPager.currentItem - val template = tempModel!!.getTemplate(ordinal) - // Don't do anything if only one template - if (tempModel.templateCount < 2) { - mTemplateEditor.showSimpleMessageDialog(res.getString(R.string.card_template_editor_cant_delete)) - return true - } - - if (deletionWouldOrphanNote(col, tempModel, ordinal)) { - return true - } - - // Show confirmation dialog - val numAffectedCards = if (!TemporaryModel.isOrdinalPendingAdd(tempModel, ordinal)) { - Timber.d("Ordinal is not a pending add, so we'll get the current card count for confirmation") - col.models.tmplUseCount(tempModel.model, ordinal) - } else { - 0 - } - confirmDeleteCards(template, tempModel.model, numAffectedCards) - return true - } else if (itemId == R.id.action_add_deck_override) { - displayDeckOverrideDialog(col, tempModel) - return true - } else if (itemId == R.id.action_preview) { - performPreview() - return true - } else if (itemId == R.id.action_confirm) { - Timber.i("CardTemplateEditor:: Save model button pressed") - if (modelHasChanged()) { - val confirmButton = mTemplateEditor.findViewById(R.id.action_confirm) - if (confirmButton != null) { - if (!confirmButton.isEnabled) { - Timber.d("CardTemplateEditor::discarding extra click after button disabled") - return true - } - confirmButton.isEnabled = false + when (menuItem.itemId) { + R.id.action_add -> { + Timber.i("CardTemplateEditor:: Add template button pressed") + // Show confirmation dialog + val ordinal = mTemplateEditor.viewPager.currentItem + // isOrdinalPendingAdd method will check if there are any new card types added or not, + // if TempModel has new card type then numAffectedCards will be 0 by default. + val numAffectedCards = if (!TemporaryModel.isOrdinalPendingAdd(tempModel!!, ordinal)) { + col.models.tmplUseCount(tempModel.model, ordinal) + } else { + 0 } - tempModel!!.saveToDatabase(saveModelAndExitHandler()) - } else { - Timber.d("CardTemplateEditor:: model has not changed, exiting") - mTemplateEditor.finishWithAnimation(END) + confirmAddCards(tempModel.model, numAffectedCards) + return true } + R.id.action_insert_field -> showInsertFieldDialog() + R.id.action_delete -> { + Timber.i("CardTemplateEditor:: Delete template button pressed") + val res = resources + val ordinal = mTemplateEditor.viewPager.currentItem + val template = tempModel!!.getTemplate(ordinal) + // Don't do anything if only one template + if (tempModel.templateCount < 2) { + mTemplateEditor.showSimpleMessageDialog(res.getString(R.string.card_template_editor_cant_delete)) + return true + } - return true - } else if (itemId == R.id.action_card_browser_appearance) { - Timber.i("CardTemplateEditor::Card Browser Template button pressed") - val currentTemplate = getCurrentTemplate() - currentTemplate?.let { launchCardBrowserAppearance(it) } - return true + if (deletionWouldOrphanNote(col, tempModel, ordinal)) { + return true + } + + // Show confirmation dialog + val numAffectedCards = if (!TemporaryModel.isOrdinalPendingAdd(tempModel, ordinal)) { + Timber.d("Ordinal is not a pending add, so we'll get the current card count for confirmation") + col.models.tmplUseCount(tempModel.model, ordinal) + } else { + 0 + } + confirmDeleteCards(template, tempModel.model, numAffectedCards) + return true + } + R.id.action_add_deck_override -> { + displayDeckOverrideDialog(col, tempModel!!) + return true + } + R.id.action_preview -> { + performPreview() + return true + } + R.id.action_confirm -> { + Timber.i("CardTemplateEditor:: Save model button pressed") + if (modelHasChanged()) { + val confirmButton = mTemplateEditor.findViewById(R.id.action_confirm) + if (confirmButton != null) { + if (!confirmButton.isEnabled) { + Timber.d("CardTemplateEditor::discarding extra click after button disabled") + return true + } + confirmButton.isEnabled = false + } + tempModel!!.saveToDatabase(saveModelAndExitHandler()) + } else { + Timber.d("CardTemplateEditor:: model has not changed, exiting") + mTemplateEditor.finishWithAnimation(END) + } + + return true + } + R.id.action_card_browser_appearance -> { + Timber.i("CardTemplateEditor::Card Browser Template button pressed") + val currentTemplate = getCurrentTemplate() + currentTemplate?.let { launchCardBrowserAppearance(it) } + return true + } } return false } @@ -615,10 +599,9 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { onRequestPreviewResult.launch(i) } - @KotlinCleanup("Make tempModel non-null") - private fun displayDeckOverrideDialog(col: Collection, tempModel: TemporaryModel?) { + private fun displayDeckOverrideDialog(col: Collection, tempModel: TemporaryModel) { val activity = requireActivity() as AnkiActivity - if (tempModel!!.model.isCloze) { + if (tempModel.model.isCloze) { UIUtils.showThemedToast(activity, getString(R.string.multimedia_editor_something_wrong), true) return } @@ -633,11 +616,10 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { showDialogFragment(activity, dialog) } - @KotlinCleanup("Make tempModel non-null") - private fun getCurrentTemplateName(tempModel: TemporaryModel?): String { + private fun getCurrentTemplateName(tempModel: TemporaryModel): String { return try { val ordinal = mTemplateEditor.viewPager.currentItem - val template = tempModel!!.getTemplate(ordinal) + val template = tempModel.getTemplate(ordinal) template.getString("name") } catch (e: Exception) { Timber.w(e, "Failed to get name for template") @@ -647,12 +629,6 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { private fun launchCardBrowserAppearance(currentTemplate: JSONObject) { val context = AnkiDroidApp.instance.baseContext - @KotlinCleanup("remove if block (bug has been fixed already)") - if (context == null) { - // Catch-22, we can't notify failure as there's no context. Shouldn't happen anyway - Timber.w("Context was null - couldn't launch Card Browser Appearance window") - return - } val browserAppearanceIntent = CardTemplateBrowserAppearanceEditor.getIntentFromTemplate(context, currentTemplate) onCardBrowserAppearanceActivityResult.launch(browserAppearanceIntent) } @@ -672,7 +648,7 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { /** * @return The index of the card template which is currently referred to by the fragment */ - fun getCurrentCardTemplateIndex(): Int { + private fun getCurrentCardTemplateIndex(): Int { // COULD_BE_BETTER: Lots of duplicate code could call this. Hold off on the refactor until #5151 goes in. return requireArguments().getInt(CARD_INDEX) } @@ -699,15 +675,15 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { return false } - var onCardBrowserAppearanceActivityResult = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult -> + private var onCardBrowserAppearanceActivityResult = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult -> if (result.resultCode != RESULT_OK) { return@registerForActivityResult } onCardBrowserAppearanceResult(result.data) } - var onRequestPreviewResult = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult -> + private var onRequestPreviewResult = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult -> if (result.resultCode != RESULT_OK) { return@registerForActivityResult } @@ -779,12 +755,13 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { * @param model model to remove template from, modified in place by reference * @param numAffectedCards number of cards which will be affected */ - @KotlinCleanup("redundant `val res = resources`") private fun confirmDeleteCards(tmpl: JSONObject, model: Model, numAffectedCards: Int) { val d = ConfirmationDialog() - val res = resources val msg = String.format( - res.getQuantityString(R.plurals.card_template_editor_confirm_delete, numAffectedCards), + resources.getQuantityString( + R.plurals.card_template_editor_confirm_delete, + numAffectedCards + ), numAffectedCards, tmpl.optString("name") ) d.setArgs(msg) @@ -800,12 +777,13 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { * @param model model to add new template and modified in place by reference * @param numAffectedCards number of cards which will be affected */ - @KotlinCleanup("redundant `val res = resources`") private fun confirmAddCards(model: Model, numAffectedCards: Int) { val d = ConfirmationDialog() - val res = resources val msg = String.format( - res.getQuantityString(R.plurals.card_template_editor_confirm_add, numAffectedCards), + resources.getQuantityString( + R.plurals.card_template_editor_confirm_add, + numAffectedCards + ), numAffectedCards ) d.setArgs(msg) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/CardBrowserMySearchesDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/CardBrowserMySearchesDialog.kt index 905fc3598c..7e8112f6b4 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/CardBrowserMySearchesDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/CardBrowserMySearchesDialog.kt @@ -40,24 +40,20 @@ class CardBrowserMySearchesDialog : AnalyticsDialogFragment() { savedFilters?.let { savedFilterKeys = ArrayList(it.keys) } - buttonItemAdapter = ButtonItemAdapter(savedFilterKeys!!) - buttonItemAdapter!!.apply { + + buttonItemAdapter = ButtonItemAdapter( + savedFilterKeys!!, + itemCallback = { searchName -> + Timber.d("item clicked: %s", searchName) + mySearchesDialogListener!!.onSelection(searchName) + dialog.dismiss() + }, + buttonCallback = { searchName -> + Timber.d("button clicked: %s", searchName) + removeSearch(searchName) + } + ).apply { notifyAdapterDataSetChanged() // so the values are sorted. - setCallbacks( - object : ButtonItemAdapter.ItemCallback { - override fun onItemClicked(searchName: String) { - Timber.d("item clicked: %s", searchName) - mySearchesDialogListener!!.onSelection(searchName) - dialog.dismiss() - } - }, - object : ButtonItemAdapter.ButtonCallback { - override fun onButtonClicked(searchName: String) { - Timber.d("button clicked: %s", searchName) - removeSearch(searchName) - } - } - ) dialog.title(text = resources.getString(R.string.card_browser_list_my_searches_title)) .customListAdapter(this, null) } diff --git a/AnkiDroid/src/main/java/com/ichi2/ui/ButtonItemAdapter.kt b/AnkiDroid/src/main/java/com/ichi2/ui/ButtonItemAdapter.kt index a5d3291f01..fe1bc168df 100644 --- a/AnkiDroid/src/main/java/com/ichi2/ui/ButtonItemAdapter.kt +++ b/AnkiDroid/src/main/java/com/ichi2/ui/ButtonItemAdapter.kt @@ -32,29 +32,20 @@ import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.ichi2.anki.R import com.ichi2.ui.ButtonItemAdapter.ButtonVH -import com.ichi2.utils.KotlinCleanup -import java.util.* /** * RecyclerView.Adapter class copied almost completely from the Material Dialogs library example * {@see [](https://github.com/afollestad/material-dialogs/blob/0.9.6.0/sample/src/main/java/com/afollestad/materialdialogssample/ButtonItemAdapter.java>ButtonItemAdapter.java ) */ -@KotlinCleanup("Fix all IDE lint issues") -class ButtonItemAdapter(private val items: kotlin.collections.ArrayList) : RecyclerView.Adapter() { - @KotlinCleanup("make field non null") - private var mItemCallback: ItemCallback? = null - @KotlinCleanup("make field non null") - private var mButtonCallback: ButtonCallback? = null - +class ButtonItemAdapter( + private val items: ArrayList, + private val itemCallback: ItemCallback, + private val buttonCallback: ButtonCallback +) : RecyclerView.Adapter() { fun remove(searchName: String) { items.remove(searchName) } - fun setCallbacks(itemCallback: ItemCallback, buttonCallback: ButtonCallback) { - mItemCallback = itemCallback - mButtonCallback = buttonCallback - } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ButtonVH { val view = LayoutInflater.from(parent.context) .inflate(R.layout.card_browser_item_my_searches_dialog, parent, false) @@ -62,46 +53,28 @@ class ButtonItemAdapter(private val items: kotlin.collections.ArrayList) } override fun onBindViewHolder(holder: ButtonVH, position: Int) { - holder.mTitle.text = items[position] - holder.mButton.tag = items[position] + holder.title.text = items[position] + holder.button.tag = items[position] } - override fun getItemCount(): Int { - return items.size - } + override fun getItemCount() = items.size - @KotlinCleanup("make this a fun interface to use a lambda at the call site") - interface ItemCallback { - fun onItemClicked(searchName: String) - } - - @KotlinCleanup("make this a fun interface to use a lambda at the call site") - interface ButtonCallback { - fun onButtonClicked(searchName: String) - } - - inner class ButtonVH constructor(itemView: View, adapter: ButtonItemAdapter) : RecyclerView.ViewHolder(itemView), View.OnClickListener { - val mTitle: TextView - val mButton: ImageButton - private val mAdapter: ButtonItemAdapter + inner class ButtonVH constructor(itemView: View, private val adapter: ButtonItemAdapter) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + val title: TextView = itemView.findViewById(R.id.card_browser_my_search_name_textview) + val button: ImageButton = itemView.findViewById(R.id.card_browser_my_search_remove_button).apply { + setOnClickListener(this@ButtonVH) + } override fun onClick(view: View) { - if (mAdapter.mItemCallback == null) { - return - } if (view is ImageButton) { - mAdapter.mButtonCallback!!.onButtonClicked(items[bindingAdapterPosition]) + adapter.buttonCallback.onButtonClicked(items[bindingAdapterPosition]) } else { - mAdapter.mItemCallback!!.onItemClicked(items[bindingAdapterPosition]) + adapter.itemCallback.onItemClicked(items[bindingAdapterPosition]) } } init { - mTitle = itemView.findViewById(R.id.card_browser_my_search_name_textview) - mButton = itemView.findViewById(R.id.card_browser_my_search_remove_button) - mAdapter = adapter itemView.setOnClickListener(this) - mButton.setOnClickListener(this) } } @@ -113,4 +86,12 @@ class ButtonItemAdapter(private val items: kotlin.collections.ArrayList) items.sortWith { obj: String, str: String -> obj.compareTo(str, ignoreCase = true) } super.notifyDataSetChanged() } + + fun interface ItemCallback { + fun onItemClicked(searchName: String) + } + + fun interface ButtonCallback { + fun onButtonClicked(searchName: String) + } }