diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/StorageSelectDialog.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/StorageSelectDialog.kt index 481b54dcf..a72672272 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/StorageSelectDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/StorageSelectDialog.kt @@ -13,7 +13,6 @@ import org.koitharu.kotatsu.databinding.ItemStorageBinding import org.koitharu.kotatsu.local.domain.LocalMangaRepository import org.koitharu.kotatsu.utils.ext.getStorageName import org.koitharu.kotatsu.utils.ext.inflate -import org.koitharu.kotatsu.utils.ext.longHashCode import java.io.File class StorageSelectDialog private constructor(private val delegate: AlertDialog) : @@ -30,10 +29,10 @@ class StorageSelectDialog private constructor(private val delegate: AlertDialog) if (adapter.isEmpty) { delegate.setMessage(R.string.cannot_find_available_storage) } else { - val checked = adapter.volumes.indexOfFirst { + adapter.selectedItemPosition = adapter.volumes.indexOfFirst { it.first.canonicalPath == defaultValue?.canonicalPath } - delegate.setSingleChoiceItems(adapter, checked) { d, i -> + delegate.setAdapter(adapter) { d, i -> listener.onStorageSelected(adapter.getItem(i).first) d.dismiss() } @@ -60,12 +59,16 @@ class StorageSelectDialog private constructor(private val delegate: AlertDialog) private class VolumesAdapter(context: Context) : BaseAdapter() { + var selectedItemPosition: Int = -1 val volumes = getAvailableVolumes(context) override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { val view = convertView ?: parent.inflate(R.layout.item_storage) + val binding = (view.tag as? ItemStorageBinding) ?: ItemStorageBinding.bind(view).also { + view.tag = it + } val item = volumes[position] - val binding = ItemStorageBinding.bind(view) + binding.imageViewIndicator.isChecked = selectedItemPosition == position binding.textViewTitle.text = item.second binding.textViewSubtitle.text = item.first.path return view @@ -73,23 +76,21 @@ class StorageSelectDialog private constructor(private val delegate: AlertDialog) override fun getItem(position: Int): Pair = volumes[position] - override fun getItemId(position: Int) = volumes[position].first.absolutePath.longHashCode() + override fun getItemId(position: Int) = position.toLong() override fun getCount() = volumes.size + override fun hasStableIds() = true + + private fun getAvailableVolumes(context: Context): List> { + return LocalMangaRepository.getAvailableStorageDirs(context).map { + it to it.getStorageName(context) + } + } } fun interface OnStorageSelectListener { fun onStorageSelected(file: File) } - - private companion object { - - fun getAvailableVolumes(context: Context): List> { - return LocalMangaRepository.getAvailableStorageDirs(context).map { - it to it.getStorageName(context) - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/CheckableImageView.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/CheckableImageView.kt index 472f95a78..9c8366293 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/CheckableImageView.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/CheckableImageView.kt @@ -1,12 +1,19 @@ package org.koitharu.kotatsu.base.ui.widgets import android.content.Context +import android.os.Parcel +import android.os.Parcelable +import android.os.Parcelable.Creator import android.util.AttributeSet import android.widget.Checkable +import androidx.annotation.AttrRes import androidx.appcompat.widget.AppCompatImageView +import androidx.core.os.ParcelCompat class CheckableImageView @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 + context: Context, + attrs: AttributeSet? = null, + @AttrRes defStyleAttr: Int = 0, ) : AppCompatImageView(context, attrs, defStyleAttr), Checkable { private var isCheckedInternal = false @@ -14,20 +21,6 @@ class CheckableImageView @JvmOverloads constructor( var onCheckedChangeListener: OnCheckedChangeListener? = null - init { - setOnClickListener { - toggle() - } - } - - fun setOnCheckedChangeListener(listener: (Boolean) -> Unit) { - onCheckedChangeListener = object : OnCheckedChangeListener { - override fun onCheckedChanged(view: CheckableImageView, isChecked: Boolean) { - listener(isChecked) - } - } - } - override fun isChecked() = isCheckedInternal override fun toggle() { @@ -49,18 +42,54 @@ class CheckableImageView @JvmOverloads constructor( override fun onCreateDrawableState(extraSpace: Int): IntArray { val state = super.onCreateDrawableState(extraSpace + 1) if (isCheckedInternal) { - mergeDrawableStates(state, CHECKED_STATE_SET) + mergeDrawableStates(state, intArrayOf(android.R.attr.state_checked)) } return state } + override fun onSaveInstanceState(): Parcelable? { + val superState = super.onSaveInstanceState() ?: return null + return SavedState(superState, isChecked) + } + + override fun onRestoreInstanceState(state: Parcelable?) { + if (state is SavedState) { + super.onRestoreInstanceState(state.superState) + isChecked = state.isChecked + } else { + super.onRestoreInstanceState(state) + } + } + fun interface OnCheckedChangeListener { fun onCheckedChanged(view: CheckableImageView, isChecked: Boolean) } - private companion object { + private class SavedState : BaseSavedState { - private val CHECKED_STATE_SET = intArrayOf(android.R.attr.state_checked) + val isChecked: Boolean + + constructor(superState: Parcelable, checked: Boolean) : super(superState) { + isChecked = checked + } + + constructor(source: Parcel) : super(source) { + isChecked = ParcelCompat.readBoolean(source) + } + + override fun writeToParcel(out: Parcel, flags: Int) { + super.writeToParcel(out, flags) + ParcelCompat.writeBoolean(out, isChecked) + } + + companion object { + @JvmField + val CREATOR: Creator = object : Creator { + override fun createFromParcel(`in`: Parcel) = SavedState(`in`) + + override fun newArray(size: Int): Array = arrayOfNulls(size) + } + } } } \ No newline at end of file diff --git a/app/src/main/res/layout/item_storage.xml b/app/src/main/res/layout/item_storage.xml index 862e417ce..3df31113f 100644 --- a/app/src/main/res/layout/item_storage.xml +++ b/app/src/main/res/layout/item_storage.xml @@ -1,22 +1,32 @@ - + + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 36181a691..27c27a4e9 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -133,6 +133,7 @@ \ No newline at end of file diff --git a/app/src/main/res/xml/pref_main.xml b/app/src/main/res/xml/pref_main.xml index 6a6c72594..21743702c 100644 --- a/app/src/main/res/xml/pref_main.xml +++ b/app/src/main/res/xml/pref_main.xml @@ -31,7 +31,7 @@ android:title="@string/date_format" app:iconSpaceReserved="false" /> -