Skip to content

Commit

Permalink
Implement EditTextPreference
Browse files Browse the repository at this point in the history
  • Loading branch information
Maxr1998 committed Dec 10, 2020
1 parent e26cc68 commit 79b2428
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ inline fun PreferenceScreen.Appendable.multiChoice(key: String, items: List<Sele
return MultiChoiceDialogPreference(key, items).apply(block).also(::addPreferenceItem)
}

inline fun PreferenceScreen.Appendable.editText(key: String, block: EditTextPreference.() -> Unit): EditTextPreference {
return EditTextPreference(key).apply(block).also(::addPreferenceItem)
}

inline fun <reified T : Preference> PreferenceScreen.Appendable.custom(key: String, block: T.() -> Unit): T {
return T::class.java.getConstructor(String::class.java).newInstance(key).apply(block).also(::addPreferenceItem)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package de.Maxr1998.modernpreferences.preferences

import android.app.Dialog
import android.content.Context
import android.text.InputType
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.FrameLayout
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.AppCompatEditText

class EditTextPreference(key: String) : DialogPreference(key) {

var currentInput: CharSequence? = null
private set

/**
* The [InputType] applied to the contained [EditText][AppCompatEditText]
*/
var textInputType: Int = InputType.TYPE_NULL

@StringRes
var textInputHintRes: Int = -1
var textInputHint: CharSequence? = null

var textChangeListener: OnTextChangeListener? = null

/**
* Allows to override the summary, providing the current input value when called.
*
* Summary falls back to [summary] or [summaryRes] when null is returned.
*/
var summaryProvider: (CharSequence?) -> CharSequence? = { null }

override fun onAttach() {
super.onAttach()
if (currentInput == null)
currentInput = getString()
}

override fun createDialog(context: Context): Dialog = AlertDialog.Builder(context).apply {
if (titleRes != -1) setTitle(titleRes) else setTitle(title)
val editText = AppCompatEditText(context).apply {
if (textInputType != InputType.TYPE_NULL) {
inputType = textInputType
}
when {
textInputHintRes != -1 -> setHint(textInputHintRes)
textInputHint != null -> hint = textInputHint
}
setText(currentInput)
}
setView(FrameLayout(context).apply {
val layoutParams = ViewGroup.MarginLayoutParams(MATCH_PARENT, WRAP_CONTENT).apply {
val tenDp = (10 * context.resources.displayMetrics.density).toInt()
marginStart = 2 * tenDp
marginEnd = 2 * tenDp
topMargin = tenDp
}
addView(editText, layoutParams)
})
setCancelable(false)
setPositiveButton(android.R.string.ok) { _, _ ->
editText.text?.let(::persist)
requestRebind()
}
setNegativeButton(android.R.string.cancel) { _, _ ->
editText.setText(currentInput)
}
}.create()

private fun persist(input: CharSequence) {
if (textChangeListener?.onTextChange(this, input) != false) {
currentInput = input
commitString(input.toString())
}
}

override fun resolveSummary(context: Context): CharSequence? {
return summaryProvider(currentInput) ?: super.resolveSummary(context)
}

fun interface OnTextChangeListener {
/**
* Notified when the value of the connected [EditTextPreference] changes,
* meaning after the user closes the dialog by pressing "ok".
* This is called before the change gets persisted and can be prevented by returning false.
*
* @param text the new value
*
* @return true to commit the new value to [SharedPreferences][android.content.SharedPreferences]
*/
fun onTextChange(preference: EditTextPreference, text: CharSequence): Boolean
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ object Common {
multiChoice("multi-choice-dialog", selectableItems) {
title = "Multi choice selection dialog"
}
editText("edit-text") {
title = "Text input"
textInputHint = "Enter whatever you want!"
}
expandText("expand-text") {
title = "Expandable text"
text = "This is an example implementation of ModernAndroidPreferences, check out " +
Expand Down

0 comments on commit 79b2428

Please sign in to comment.