diff options
8 files changed, 156 insertions, 89 deletions
diff --git a/library/src/main/kotlin/ca/allanwang/kau/kpref/KPrefBinder.kt b/library/src/main/kotlin/ca/allanwang/kau/kpref/KPrefBinder.kt index 62f3d45..cc267d6 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/kpref/KPrefBinder.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/kpref/KPrefBinder.kt @@ -5,12 +5,8 @@ import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import ca.allanwang.kau.R import ca.allanwang.kau.dialogs.color.Builder -import ca.allanwang.kau.kpref.items.KPrefCheckbox -import ca.allanwang.kau.kpref.items.KPrefColorPicker -import ca.allanwang.kau.kpref.items.KPrefHeader -import ca.allanwang.kau.kpref.items.KPrefItemCore +import ca.allanwang.kau.kpref.items.* import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter -import com.mikepenz.iconics.typeface.IIcon /** * Created by Allan Wang on 2017-06-08. @@ -34,20 +30,15 @@ class KPrefAdapterBuilder { fun header(@StringRes title: Int) = list.add(KPrefHeader(this, title)) fun checkbox(@StringRes title: Int, - @StringRes description: Int = -1, - iicon: IIcon? = null, - enabler: () -> Boolean = { true }, - getter: () -> Boolean, - setter: (value: Boolean) -> Unit) = list.add(KPrefCheckbox(this, title, description, iicon, enabler, getter, setter)) + coreBuilder: KPrefItemCore.Builder.() -> Unit = {}, + itemBuilder: KPrefItemBase.Builder<Boolean>.() -> Unit = {}) = list.add(KPrefCheckbox( + this, title, coreBuilder, itemBuilder)) fun colorPicker(@StringRes title: Int, - @StringRes description: Int = -1, - iicon: IIcon? = null, - enabler: () -> Boolean = { true }, - getter: () -> Int, - setter: (value: Int) -> Unit, - configs: Builder.() -> Unit = {}, - showPreview: Boolean = true) = list.add(KPrefColorPicker(this, title, description, iicon, enabler, getter, setter, configs, showPreview)) + coreBuilder: KPrefItemCore.Builder.() -> Unit = {}, + itemBuilder: KPrefItemBase.Builder<Int>.() -> Unit = {}, + colorBuilder: Builder.() -> Unit = {}, + showPreview: Boolean = true) = list.add(KPrefColorPicker(this, title, coreBuilder, itemBuilder, colorBuilder, showPreview)) internal val list: MutableList<KPrefItemCore> = mutableListOf() diff --git a/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefCheckbox.kt b/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefCheckbox.kt index e09e245..cc09a33 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefCheckbox.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefCheckbox.kt @@ -6,7 +6,6 @@ import android.widget.CheckBox import ca.allanwang.kau.R import ca.allanwang.kau.kpref.KPrefAdapterBuilder import ca.allanwang.kau.utils.tint -import com.mikepenz.iconics.typeface.IIcon /** * Created by Allan Wang on 2017-06-07. @@ -16,14 +15,11 @@ import com.mikepenz.iconics.typeface.IIcon */ class KPrefCheckbox(builder: KPrefAdapterBuilder, @StringRes title: Int, - @StringRes description: Int = -1, - iicon: IIcon? = null, - enabler: () -> Boolean = { true }, - getter: () -> Boolean, - setter: (value: Boolean) -> Unit) : KPrefItemBase<Boolean>(builder, title, description, iicon, enabler, getter, setter) { + coreBuilder: KPrefItemCore.Builder.() -> Unit = {}, + itemBuilder: Builder<Boolean>.() -> Unit = {} +) : KPrefItemBase<Boolean>(builder, title, coreBuilder, itemBuilder) { - - override fun onClick(itemView: View, innerContent: View?): Boolean { + override fun defaultOnClick(itemView: View, innerContent: View?): Boolean { pref = !pref (innerContent as CheckBox).isChecked = pref return true diff --git a/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefColorPicker.kt b/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefColorPicker.kt index f157d1c..3d1ad21 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefColorPicker.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefColorPicker.kt @@ -3,11 +3,9 @@ package ca.allanwang.kau.kpref.items import android.support.annotation.StringRes import android.view.View import ca.allanwang.kau.R -import ca.allanwang.kau.dialogs.color.Builder import ca.allanwang.kau.dialogs.color.CircleView import ca.allanwang.kau.dialogs.color.colorPickerDialog import ca.allanwang.kau.kpref.KPrefAdapterBuilder -import com.mikepenz.iconics.typeface.IIcon /** * Created by Allan Wang on 2017-06-07. @@ -17,13 +15,11 @@ import com.mikepenz.iconics.typeface.IIcon */ class KPrefColorPicker(builder: KPrefAdapterBuilder, @StringRes title: Int, - @StringRes description: Int = -1, - iicon: IIcon? = null, - enabler: () -> Boolean = { true }, - getter: () -> Int, - setter: (value: Int) -> Unit, - val configs: Builder.() -> Unit = {}, - val showPreview: Boolean = false) : KPrefItemBase<Int>(builder, title, description, iicon, enabler, getter, setter) { + coreBuilder: KPrefItemCore.Builder.() -> Unit = {}, + itemBuilder: KPrefItemBase.Builder<Int>.() -> Unit = {}, + val colorBuilder: ca.allanwang.kau.dialogs.color.Builder.() -> Unit = {}, + val showPreview: Boolean = false +) : KPrefItemBase<Int>(builder, title, coreBuilder, itemBuilder) { override fun onPostBindView(viewHolder: ViewHolder, textColor: Int?, accentColor: Int?) { super.onPostBindView(viewHolder, textColor, accentColor) @@ -36,7 +32,7 @@ class KPrefColorPicker(builder: KPrefAdapterBuilder, } - override fun onClick(itemView: View, innerContent: View?): Boolean { + override fun defaultOnClick(itemView: View, innerContent: View?): Boolean { itemView.context.colorPickerDialog { titleRes = this@KPrefColorPicker.title defaultColor = pref @@ -45,7 +41,7 @@ class KPrefColorPicker(builder: KPrefAdapterBuilder, if (showPreview) (innerContent as CircleView).setBackgroundColor(it) } - applyNestedBuilder(configs) + applyNestedBuilder(colorBuilder) }.show() return true } diff --git a/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefItemBase.kt b/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefItemBase.kt index a15dcc3..4c12961 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefItemBase.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefItemBase.kt @@ -2,9 +2,12 @@ package ca.allanwang.kau.kpref.items import android.support.annotation.CallSuper import android.support.annotation.StringRes +import android.view.View import ca.allanwang.kau.R import ca.allanwang.kau.kpref.KPrefAdapterBuilder -import com.mikepenz.iconics.typeface.IIcon +import ca.allanwang.kau.kpref.KPrefException +import ca.allanwang.kau.utils.resolveDrawable +import ca.allanwang.kau.utils.string /** * Created by Allan Wang on 2017-06-05. @@ -14,34 +17,62 @@ import com.mikepenz.iconics.typeface.IIcon abstract class KPrefItemBase<T>(builder: KPrefAdapterBuilder, @StringRes title: Int, - @StringRes description: Int = -1, - iicon: IIcon? = null, - val enabler: () -> Boolean = { true }, - private val getter: () -> T, - private val setter: (value: T) -> Unit) : KPrefItemCore(builder, title, description, iicon) { + coreBuilder: KPrefItemCore.Builder.() -> Unit = {}, + itemBuilder: Builder<T>.() -> Unit = {}) : KPrefItemCore(builder, title, coreBuilder) { var pref: T - get() = getter.invoke() + get() = itemBase.getter!!.invoke() set(value) { - setter.invoke(value) + itemBase.setter!!.invoke(value) } + var enabled: Boolean = true + val itemBase: Builder<T> + + init { + itemBase = Builder<T>() + itemBase.itemBuilder() + if (itemBase.onClick == null) itemBase.onClick = { + itemView, innerContent -> + defaultOnClick(itemView, innerContent) + } + } + + abstract fun defaultOnClick(itemView: View, innerContent: View?): Boolean + @CallSuper override fun onPostBindView(viewHolder: ViewHolder, textColor: Int?, accentColor: Int?) { - val enabled = enabler.invoke() + val c = viewHolder.itemView.context + if (itemBase.getter == null) throw KPrefException("getter not set for ${c.string(title)}") + if (itemBase.setter == null) throw KPrefException("setter not set for ${c.string(title)}") + enabled = itemBase.enabler.invoke() with(viewHolder) { - itemView.isEnabled = enabled + if (!enabled) container?.background = null container?.alpha = if (enabled) 1.0f else 0.3f } } + override final fun onClick(itemView: View, innerContent: View?): Boolean { + return if (enabled) itemBase.onClick?.invoke(itemView, innerContent) ?: false + else itemBase.onDisabledClick?.invoke(itemView, innerContent) ?: false + } + override fun unbindView(holder: ViewHolder) { super.unbindView(holder) with(holder) { - itemView.isEnabled = true + container?.isEnabled = true + container?.background = itemView.context.resolveDrawable(android.R.attr.selectableItemBackground) container?.alpha = 1.0f } } override final fun getLayoutRes(): Int = R.layout.kau_preference + + open class Builder<T> { + var enabler: () -> Boolean = { true } + var onClick: ((itemView: View, innerContent: View?) -> Boolean)? = null + var onDisabledClick: ((itemView: View, innerContent: View?) -> Boolean)? = null + var getter: (() -> T)? = null + var setter: ((value: T) -> Unit)? = null + } }
\ No newline at end of file diff --git a/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefItemCore.kt b/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefItemCore.kt index 8d5eca2..b5741b0 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefItemCore.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/kpref/items/KPrefItemCore.kt @@ -27,22 +27,28 @@ import com.mikepenz.iconics.typeface.IIcon abstract class KPrefItemCore(val builder: KPrefAdapterBuilder, @StringRes val title: Int, - @StringRes val description: Int = -1, - val iicon: IIcon? = null) : AbstractItem<KPrefItemCore, KPrefItemCore.ViewHolder>() { + coreBuilder: Builder.() -> Unit = {}) : AbstractItem<KPrefItemCore, KPrefItemCore.ViewHolder>() { override final fun getViewHolder(v: View) = ViewHolder(v) + val core: Builder + + init { + core = Builder() + core.coreBuilder() + } + @CallSuper override fun bindView(viewHolder: ViewHolder, payloads: List<Any>) { super.bindView(viewHolder, payloads) with(viewHolder) { val context = itemView.context title.text = context.string(this@KPrefItemCore.title) - if (description > 0) - desc?.visible()?.setText(description) + if (core.description > 0) + desc?.visible()?.setText(core.description) else desc?.gone() - if (iicon != null) icon?.visible()?.setIcon(iicon, 24) + if (core.iicon != null) icon?.visible()?.setIcon(core.iicon, 24) else icon?.gone() innerFrame?.removeAllViews() val textColor = builder.textColor?.invoke() @@ -72,6 +78,11 @@ abstract class KPrefItemCore(val builder: KPrefAdapterBuilder, } } + class Builder { + var description: Int = -1 + var iicon: IIcon? = null + } + class ViewHolder(v: View) : RecyclerView.ViewHolder(v) { val title: TextView by bindView(R.id.kau_pref_title) val container: ViewGroup? by bindOptionalView(R.id.kau_pref_container) diff --git a/library/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt b/library/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt index 87bc547..b6da0cb 100644 --- a/library/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt +++ b/library/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt @@ -94,6 +94,15 @@ fun Context.resolveColor(@AttrRes attr: Int, fallback: Int = 0): Int { } } +fun Context.resolveDrawable(@AttrRes attr: Int): Drawable? { + val a = theme.obtainStyledAttributes(intArrayOf(attr)) + try { + return a.getDrawable(0) + } finally { + a.recycle() + } +} + fun Context.resolveBoolean(@AttrRes attr: Int, fallback: Boolean = false): Boolean { val a = theme.obtainStyledAttributes(intArrayOf(attr)) try { diff --git a/library/src/main/res/layout/kau_preference.xml b/library/src/main/res/layout/kau_preference.xml index 677b0dc..c49951b 100644 --- a/library/src/main/res/layout/kau_preference.xml +++ b/library/src/main/res/layout/kau_preference.xml @@ -7,18 +7,18 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?android:attr/selectableItemBackground" android:baselineAligned="false" android:clipToPadding="false" android:minHeight="?android:attr/listPreferredItemHeightSmall" - android:orientation="horizontal" - android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" - android:paddingStart="?android:attr/listPreferredItemPaddingStart"> + android:orientation="horizontal"> <android.support.constraint.ConstraintLayout android:id="@+id/kau_pref_container" android:layout_width="match_parent" - android:layout_height="wrap_content"> + android:layout_height="wrap_content" + android:background="?android:attr/selectableItemBackground" + android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" + android:paddingStart="?android:attr/listPreferredItemPaddingStart"> <!--As per Android N, icons (24dp) are aligned to the left rather than centered--> @@ -72,10 +72,10 @@ android:id="@+id/kau_pref_barrier" android:layout_width="1dp" android:layout_height="wrap_content" - app:constraint_referenced_ids="kau_pref_title,kau_pref_desc" app:barrierDirection="end" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent" /> + app:constraint_referenced_ids="kau_pref_title,kau_pref_desc" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintTop_toTopOf="parent" /> <LinearLayout android:id="@id/kau_pref_inner_frame" diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt index 2b11ced..bf324a0 100644 --- a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt +++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt @@ -8,6 +8,7 @@ import ca.allanwang.kau.kpref.KPrefAdapterBuilder import ca.allanwang.kau.utils.darken import ca.allanwang.kau.utils.navigationBarColor import ca.allanwang.kau.utils.startActivitySlideIn +import ca.allanwang.kau.utils.toast import ca.allanwang.kau.views.RippleCanvas import com.mikepenz.google_material_typeface_library.GoogleMaterial @@ -17,36 +18,68 @@ class MainActivity : KPrefActivity() { override fun onCreateKPrefs(savedInstanceState: android.os.Bundle?): KPrefAdapterBuilder.() -> Unit = { textColor = { KPrefSample.textColor } accentColor = { KPrefSample.accentColor } + header(R.string.header) - checkbox(title = R.string.checkbox_1, description = R.string.desc, - getter = { KPrefSample.check1 }, setter = { KPrefSample.check1 = it }) - checkbox(title = R.string.checkbox_2, - getter = { KPrefSample.check2 }, setter = { KPrefSample.check2 = it; reload(3) }) - checkbox(title = R.string.checkbox_3, description = R.string.desc_dependent, enabler = { KPrefSample.check2 }, - getter = { KPrefSample.check3 }, setter = { KPrefSample.check3 = it }) - colorPicker(title = R.string.text_color, description = R.string.color_custom, - getter = { KPrefSample.textColor }, setter = { KPrefSample.textColor = it; reload() }, - configs = { - allowCustom = true - }) - colorPicker(title = R.string.accent_color, description = R.string.color_no_custom, - getter = { KPrefSample.accentColor }, setter = { - KPrefSample.accentColor = it - reload() - val darkerColor = it.darken() - this@MainActivity.navigationBarColor = darkerColor - toolbarCanvas.ripple(darkerColor, RippleCanvas.MIDDLE, RippleCanvas.END, duration = 500L) - }, - configs = { - allowCustom = false - }) - colorPicker(iicon = GoogleMaterial.Icon.gmd_colorize, - title = R.string.background_color, description = R.string.color_custom_alpha, - getter = { KPrefSample.bgColor }, setter = { KPrefSample.bgColor = it; bgCanvas.ripple(it, duration = 500L) }, - configs = { - allowCustomAlpha = true - allowCustom = true - }) + + checkbox(title = R.string.checkbox_1, coreBuilder = { + description = R.string.desc + }, itemBuilder = { + getter = { KPrefSample.check1 } + setter = { KPrefSample.check1 = it } + }) + + checkbox(title = R.string.checkbox_2, itemBuilder = { + getter = { KPrefSample.check2 } + setter = { KPrefSample.check2 = it; reload(3) } + }) + + checkbox(title = R.string.checkbox_3, coreBuilder = { + description = R.string.desc_dependent + }, itemBuilder = { + enabler = { KPrefSample.check2 } + getter = { KPrefSample.check3 } + setter = { KPrefSample.check3 = it } + onDisabledClick = { + itemView, innerContent -> + itemView.context.toast("I am still disabled") + true + } + }) + + colorPicker(title = R.string.text_color, coreBuilder = { + description = R.string.color_custom + }, itemBuilder = { + getter = { KPrefSample.textColor } + setter = { KPrefSample.textColor = it; reload() } + }, colorBuilder = { + allowCustom = true + }) + + colorPicker(title = R.string.accent_color, coreBuilder = { + description = R.string.color_no_custom + }, itemBuilder = { + getter = { KPrefSample.accentColor } + setter = { + KPrefSample.accentColor = it + reload() + val darkerColor = it.darken() + this@MainActivity.navigationBarColor = darkerColor + toolbarCanvas.ripple(darkerColor, RippleCanvas.MIDDLE, RippleCanvas.END, duration = 500L) + } + }, colorBuilder = { + allowCustom = false + }) + + colorPicker(title = R.string.background_color, coreBuilder = { + iicon = GoogleMaterial.Icon.gmd_colorize + description = R.string.color_custom_alpha + }, itemBuilder = { + getter = { KPrefSample.bgColor } + setter = { KPrefSample.bgColor = it; bgCanvas.ripple(it, duration = 500L) } + }, colorBuilder = { + allowCustomAlpha = true + allowCustom = true + }) } override fun onCreate(savedInstanceState: Bundle?) { |