Fix some settings ui

pull/104/head
Koitharu 4 years ago
parent 3bd67e2098
commit 07634d01f3
No known key found for this signature in database
GPG Key ID: 8E861F8CE6E7CE27

@ -13,7 +13,6 @@ import org.koitharu.kotatsu.databinding.ItemStorageBinding
import org.koitharu.kotatsu.local.domain.LocalMangaRepository import org.koitharu.kotatsu.local.domain.LocalMangaRepository
import org.koitharu.kotatsu.utils.ext.getStorageName import org.koitharu.kotatsu.utils.ext.getStorageName
import org.koitharu.kotatsu.utils.ext.inflate import org.koitharu.kotatsu.utils.ext.inflate
import org.koitharu.kotatsu.utils.ext.longHashCode
import java.io.File import java.io.File
class StorageSelectDialog private constructor(private val delegate: AlertDialog) : class StorageSelectDialog private constructor(private val delegate: AlertDialog) :
@ -30,10 +29,10 @@ class StorageSelectDialog private constructor(private val delegate: AlertDialog)
if (adapter.isEmpty) { if (adapter.isEmpty) {
delegate.setMessage(R.string.cannot_find_available_storage) delegate.setMessage(R.string.cannot_find_available_storage)
} else { } else {
val checked = adapter.volumes.indexOfFirst { adapter.selectedItemPosition = adapter.volumes.indexOfFirst {
it.first.canonicalPath == defaultValue?.canonicalPath it.first.canonicalPath == defaultValue?.canonicalPath
} }
delegate.setSingleChoiceItems(adapter, checked) { d, i -> delegate.setAdapter(adapter) { d, i ->
listener.onStorageSelected(adapter.getItem(i).first) listener.onStorageSelected(adapter.getItem(i).first)
d.dismiss() d.dismiss()
} }
@ -60,12 +59,16 @@ class StorageSelectDialog private constructor(private val delegate: AlertDialog)
private class VolumesAdapter(context: Context) : BaseAdapter() { private class VolumesAdapter(context: Context) : BaseAdapter() {
var selectedItemPosition: Int = -1
val volumes = getAvailableVolumes(context) val volumes = getAvailableVolumes(context)
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view = convertView ?: parent.inflate(R.layout.item_storage) 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 item = volumes[position]
val binding = ItemStorageBinding.bind(view) binding.imageViewIndicator.isChecked = selectedItemPosition == position
binding.textViewTitle.text = item.second binding.textViewTitle.text = item.second
binding.textViewSubtitle.text = item.first.path binding.textViewSubtitle.text = item.first.path
return view return view
@ -73,23 +76,21 @@ class StorageSelectDialog private constructor(private val delegate: AlertDialog)
override fun getItem(position: Int): Pair<File, String> = volumes[position] override fun getItem(position: Int): Pair<File, String> = 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 getCount() = volumes.size
} override fun hasStableIds() = true
fun interface OnStorageSelectListener {
fun onStorageSelected(file: File)
}
private companion object { private fun getAvailableVolumes(context: Context): List<Pair<File, String>> {
fun getAvailableVolumes(context: Context): List<Pair<File, String>> {
return LocalMangaRepository.getAvailableStorageDirs(context).map { return LocalMangaRepository.getAvailableStorageDirs(context).map {
it to it.getStorageName(context) it to it.getStorageName(context)
} }
} }
} }
fun interface OnStorageSelectListener {
fun onStorageSelected(file: File)
}
} }

@ -1,12 +1,19 @@
package org.koitharu.kotatsu.base.ui.widgets package org.koitharu.kotatsu.base.ui.widgets
import android.content.Context import android.content.Context
import android.os.Parcel
import android.os.Parcelable
import android.os.Parcelable.Creator
import android.util.AttributeSet import android.util.AttributeSet
import android.widget.Checkable import android.widget.Checkable
import androidx.annotation.AttrRes
import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatImageView
import androidx.core.os.ParcelCompat
class CheckableImageView @JvmOverloads constructor( 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 { ) : AppCompatImageView(context, attrs, defStyleAttr), Checkable {
private var isCheckedInternal = false private var isCheckedInternal = false
@ -14,20 +21,6 @@ class CheckableImageView @JvmOverloads constructor(
var onCheckedChangeListener: OnCheckedChangeListener? = null 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 isChecked() = isCheckedInternal
override fun toggle() { override fun toggle() {
@ -49,18 +42,54 @@ class CheckableImageView @JvmOverloads constructor(
override fun onCreateDrawableState(extraSpace: Int): IntArray { override fun onCreateDrawableState(extraSpace: Int): IntArray {
val state = super.onCreateDrawableState(extraSpace + 1) val state = super.onCreateDrawableState(extraSpace + 1)
if (isCheckedInternal) { if (isCheckedInternal) {
mergeDrawableStates(state, CHECKED_STATE_SET) mergeDrawableStates(state, intArrayOf(android.R.attr.state_checked))
} }
return state 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 interface OnCheckedChangeListener {
fun onCheckedChanged(view: CheckableImageView, isChecked: Boolean) fun onCheckedChanged(view: CheckableImageView, isChecked: Boolean)
} }
private companion object { private class SavedState : BaseSavedState {
val isChecked: Boolean
constructor(superState: Parcelable, checked: Boolean) : super(superState) {
isChecked = checked
}
constructor(source: Parcel) : super(source) {
isChecked = ParcelCompat.readBoolean(source)
}
private val CHECKED_STATE_SET = intArrayOf(android.R.attr.state_checked) override fun writeToParcel(out: Parcel, flags: Int) {
super.writeToParcel(out, flags)
ParcelCompat.writeBoolean(out, isChecked)
}
companion object {
@JvmField
val CREATOR: Creator<SavedState> = object : Creator<SavedState> {
override fun createFromParcel(`in`: Parcel) = SavedState(`in`)
override fun newArray(size: Int): Array<SavedState?> = arrayOfNulls(size)
}
}
} }
} }

@ -1,22 +1,32 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground" android:background="?selectableItemBackground"
android:gravity="center_vertical" android:minHeight="?listPreferredItemHeightLarge"
android:minHeight="?attr/listPreferredItemHeightLarge" android:paddingStart="?listPreferredItemPaddingStart"
android:orientation="vertical"
android:paddingStart="?attr/listPreferredItemPaddingStart"
android:paddingTop="16dp" android:paddingTop="16dp"
android:paddingEnd="?attr/listPreferredItemPaddingEnd" android:paddingEnd="?listPreferredItemPaddingEnd"
android:paddingBottom="16dp"> android:paddingBottom="16dp">
<org.koitharu.kotatsu.base.ui.widgets.CheckableImageView
android:id="@+id/imageView_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:src="?android:listChoiceIndicatorSingle"
tools:ignore="TouchTargetSizeCheck" />
<TextView <TextView
android:id="@+id/textView_title" android:id="@+id/textView_title"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginStart="?listPreferredItemPaddingStart"
android:layout_toEndOf="@id/imageView_indicator"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:textAppearance="?attr/textAppearanceTitleSmall" android:textAppearance="?attr/textAppearanceTitleSmall"
@ -24,11 +34,15 @@
<TextView <TextView
android:id="@+id/textView_subtitle" android:id="@+id/textView_subtitle"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/textView_title"
android:layout_alignParentEnd="true"
android:layout_marginStart="?listPreferredItemPaddingStart"
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:layout_toEndOf="@id/imageView_indicator"
android:ellipsize="end" android:ellipsize="end"
android:textAppearance="?attr/textAppearanceBodyMedium" android:textAppearance="?attr/textAppearanceBodyMedium"
tools:text="@tools:sample/lorem[20]" /> tools:text="@tools:sample/lorem[20]" />
</LinearLayout> </RelativeLayout>

@ -133,6 +133,7 @@
<style name="PreferenceThemeOverlay.Kotatsu"> <style name="PreferenceThemeOverlay.Kotatsu">
<item name="preferenceCategoryTitleTextAppearance">?attr/textAppearanceBodyMedium</item> <item name="preferenceCategoryTitleTextAppearance">?attr/textAppearanceBodyMedium</item>
<item name="singleLineTitle">false</item>
</style> </style>
</resources> </resources>

@ -31,7 +31,7 @@
android:title="@string/date_format" android:title="@string/date_format"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<SwitchPreference <SwitchPreferenceCompat
android:defaultValue="true" android:defaultValue="true"
android:key="hide_toolbar" android:key="hide_toolbar"
android:title="@string/hide_toolbar" android:title="@string/hide_toolbar"

Loading…
Cancel
Save