Skip to content

Commit 79b2428

Browse files
committed
Implement EditTextPreference
1 parent e26cc68 commit 79b2428

3 files changed

Lines changed: 105 additions & 0 deletions

File tree

library/src/main/java/de/Maxr1998/modernpreferences/helpers/PreferencesDsl.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ inline fun PreferenceScreen.Appendable.multiChoice(key: String, items: List<Sele
8484
return MultiChoiceDialogPreference(key, items).apply(block).also(::addPreferenceItem)
8585
}
8686

87+
inline fun PreferenceScreen.Appendable.editText(key: String, block: EditTextPreference.() -> Unit): EditTextPreference {
88+
return EditTextPreference(key).apply(block).also(::addPreferenceItem)
89+
}
90+
8791
inline fun <reified T : Preference> PreferenceScreen.Appendable.custom(key: String, block: T.() -> Unit): T {
8892
return T::class.java.getConstructor(String::class.java).newInstance(key).apply(block).also(::addPreferenceItem)
8993
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package de.Maxr1998.modernpreferences.preferences
2+
3+
import android.app.Dialog
4+
import android.content.Context
5+
import android.text.InputType
6+
import android.view.ViewGroup
7+
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
8+
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
9+
import android.widget.FrameLayout
10+
import androidx.annotation.StringRes
11+
import androidx.appcompat.app.AlertDialog
12+
import androidx.appcompat.widget.AppCompatEditText
13+
14+
class EditTextPreference(key: String) : DialogPreference(key) {
15+
16+
var currentInput: CharSequence? = null
17+
private set
18+
19+
/**
20+
* The [InputType] applied to the contained [EditText][AppCompatEditText]
21+
*/
22+
var textInputType: Int = InputType.TYPE_NULL
23+
24+
@StringRes
25+
var textInputHintRes: Int = -1
26+
var textInputHint: CharSequence? = null
27+
28+
var textChangeListener: OnTextChangeListener? = null
29+
30+
/**
31+
* Allows to override the summary, providing the current input value when called.
32+
*
33+
* Summary falls back to [summary] or [summaryRes] when null is returned.
34+
*/
35+
var summaryProvider: (CharSequence?) -> CharSequence? = { null }
36+
37+
override fun onAttach() {
38+
super.onAttach()
39+
if (currentInput == null)
40+
currentInput = getString()
41+
}
42+
43+
override fun createDialog(context: Context): Dialog = AlertDialog.Builder(context).apply {
44+
if (titleRes != -1) setTitle(titleRes) else setTitle(title)
45+
val editText = AppCompatEditText(context).apply {
46+
if (textInputType != InputType.TYPE_NULL) {
47+
inputType = textInputType
48+
}
49+
when {
50+
textInputHintRes != -1 -> setHint(textInputHintRes)
51+
textInputHint != null -> hint = textInputHint
52+
}
53+
setText(currentInput)
54+
}
55+
setView(FrameLayout(context).apply {
56+
val layoutParams = ViewGroup.MarginLayoutParams(MATCH_PARENT, WRAP_CONTENT).apply {
57+
val tenDp = (10 * context.resources.displayMetrics.density).toInt()
58+
marginStart = 2 * tenDp
59+
marginEnd = 2 * tenDp
60+
topMargin = tenDp
61+
}
62+
addView(editText, layoutParams)
63+
})
64+
setCancelable(false)
65+
setPositiveButton(android.R.string.ok) { _, _ ->
66+
editText.text?.let(::persist)
67+
requestRebind()
68+
}
69+
setNegativeButton(android.R.string.cancel) { _, _ ->
70+
editText.setText(currentInput)
71+
}
72+
}.create()
73+
74+
private fun persist(input: CharSequence) {
75+
if (textChangeListener?.onTextChange(this, input) != false) {
76+
currentInput = input
77+
commitString(input.toString())
78+
}
79+
}
80+
81+
override fun resolveSummary(context: Context): CharSequence? {
82+
return summaryProvider(currentInput) ?: super.resolveSummary(context)
83+
}
84+
85+
fun interface OnTextChangeListener {
86+
/**
87+
* Notified when the value of the connected [EditTextPreference] changes,
88+
* meaning after the user closes the dialog by pressing "ok".
89+
* This is called before the change gets persisted and can be prevented by returning false.
90+
*
91+
* @param text the new value
92+
*
93+
* @return true to commit the new value to [SharedPreferences][android.content.SharedPreferences]
94+
*/
95+
fun onTextChange(preference: EditTextPreference, text: CharSequence): Boolean
96+
}
97+
}

testapp/src/main/java/de/Maxr1998/modernpreferences/example/Common.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ object Common {
130130
multiChoice("multi-choice-dialog", selectableItems) {
131131
title = "Multi choice selection dialog"
132132
}
133+
editText("edit-text") {
134+
title = "Text input"
135+
textInputHint = "Enter whatever you want!"
136+
}
133137
expandText("expand-text") {
134138
title = "Expandable text"
135139
text = "This is an example implementation of ModernAndroidPreferences, check out " +

0 commit comments

Comments
 (0)