Android支持EditTextPreference输入类型
Android support EditTextPreference input type
有什么方法可以指定android.support.v7.preference.EditTextPreference
的输入法类型吗?
编辑: 以下之前的答案是基于原版 android.preference.EditTextPreference
的,不幸的是不适用于 android.support.v7.preference.EditTextPreference
.
在 android.preference.EditTextPreference
中,EditText
控件以编程方式创建,并且 Preference
中的 AttributeSet
被传递给它。
android.preference.EditTextPreference
Source:
public EditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mEditText = new EditText(context, attrs);
// Give it an ID so it can be saved/restored
mEditText.setId(com.android.internal.R.id.edit);
/*
* The preference framework and view framework both have an 'enabled'
* attribute. Most likely, the 'enabled' specified in this XML is for
* the preference framework, but it was also given to the view framework.
* We reset the enabled state.
*/
mEditText.setEnabled(true);
}
White 允许我们在 Preference
本身上设置 inputType
并将其传递给 EditText
。不幸的是 android.support.v7.preference.EditTextPreference
似乎在 Layout
中创建了 EditText
有关解决此问题的想法,请参阅 this issue:
Just wanted to let you know that subclassing EditTextPreferenceDialogFragment and overriding onAddEditTextToDialogView as well as overriding PreferenceFragmentCompat#onDisplayPreferenceDialog to show that subclass as needed seems to be working fine, thanks for the help.
创建您自己的 class 扩展 EditTextPreference
并将其设置在那里。
这是我的 EditIntegerPreference
class:
public class EditIntegerPreference extends EditTextPreference {
public EditIntegerPreference(Context context) {
super(context);
}
public EditIntegerPreference(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
public EditIntegerPreference(Context context, AttributeSet attributeSet, int defStyle) {
super(context, attributeSet, defStyle);
getEditText().setInputType(InputType.TYPE_CLASS_NUMBER);
getEditText().setSelectAllOnFocus(true);
}
@Override
public String getText() {
try {
return String.valueOf(getSharedPreferences().getInt(getKey(), 0));
} catch (Exception e) {
return getSharedPreferences().getString(getKey(), "0");
}
}
@Override
public void setText(String text) {
try {
if (getSharedPreferences() != null) {
getSharedPreferences().edit().putInt(getKey(), Integer.parseInt(text)).commit();
}
} catch (Exception e) {
// TODO: This catch stinks!
}
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
getEditText().setInputType(InputType.TYPE_CLASS_NUMBER);
getEditText().setSelectAllOnFocus(true);
if (restoreValue) {
getEditText().setText(getText());
} else {
super.onSetInitialValue(restoreValue, defaultValue != null ? defaultValue : "");
}
}
}
请注意,可以将 inputType
属性添加到 EditTextPreference
android:inputType="number"
我没有走这条路的原因是我希望我的偏好存储为 Integer
而不是 String
现在可以使用 Android-Support-Preference-V7-Fix 库。
修复了 EditTextPreference
将 XML 属性(如 inputType
)转发到 EditText
, 就像最初的偏好一样。
如果您不想使用第三方库,可以为 EditTextPreference 指定布局
<EditTextPreference android:defaultValue="0"
android:key="some_key"
android:title="Title"
android:dialogLayout="@layout/preference_edit_text"/>
然后在res/layout/preference_edit_text.xml
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText android:id="@android:id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:singleLine="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginStart="21dp"
android:layout_marginEnd="21dp"/>
</android.support.constraint.ConstraintLayout>
请注意,编辑文本 ID 必须是:@android:id/edit
但是你可以在 android:inputType
字段
中随意使用任何你想要的东西
我确定有比使用 21dp
边距更好的对齐 EditText 的方法
但至少它有效
这是我从 Cory Charlton 得到的答案版本,已转移到 Jetpack 首选项并用 Kotlin 编写:
import android.content.Context
import android.content.SharedPreferences
import android.text.InputType
import android.util.AttributeSet
import androidx.preference.EditTextPreference
class EditIntegerPreference : EditTextPreference {
constructor(context: Context?) : super(context) {
setInputMethod()
}
constructor(context: Context?, attributeSet: AttributeSet?) : super(context, attributeSet) {
setInputMethod()
}
constructor(context: Context?, attributeSet: AttributeSet?, defStyle: Int) : super(
context,
attributeSet,
defStyle
) {
setInputMethod()
}
override fun getText(): String =
try {
java.lang.String.valueOf(sharedPreferences.getInt(key, 0))
} catch (e: Exception) {
"0"
}
override fun setText(text: String?) {
try {
if (text != null) {
sharedPreferences?.edit()?.putInt(key, text.toInt())?.apply()
summary = text
} else {
sharedPreferences?.remove(key)
summary = ""
}
} catch (e: Exception) {
sharedPreferences?.remove(key)
summary = ""
}
}
override fun onSetInitialValue(defaultValue: Any?) {
val defaultValueInt: Int =
when (defaultValue){
is Int -> defaultValue
is String -> try {defaultValue.toInt()} catch (ex: java.lang.Exception){0}
else -> 0
}
text = sharedPreferences.getInt(key, defaultValueInt).toString()
}
private fun setInputMethod() {
setOnBindEditTextListener {
it.inputType = InputType.TYPE_CLASS_NUMBER
}
}
fun SharedPreferences.remove(key: String) = edit().remove(key).apply()
}
Kotlin + DataStore + androidx.Preference
的解决方法
免责声明!
可能不是这样做的方法!
理想情况下应该只有:
- 将输入设置为 int
- 覆盖
DataStore
class:putInt
/getInt
扩展函数
在我的例子中,我有一个 PreferenceFragmentCompat
,所以:
fun PreferenceFragmentCompat.setNumericInput(
@StringRes prefRes: Int, initialValue: String) {
val preference = findPreference(getString(prefRes)) as EditTextPreference?
preference?.setOnBindEditTextListener { editText ->
editText.inputType = InputType.TYPE_CLASS_NUMBER or
InputType.TYPE_NUMBER_FLAG_SIGNED
// set the initial value: I read it from the DataStore and then
// pass it as the 2nd argument to setNumericInput.
// BTW, I do store stringPreferenceKeys, as it's the putString method
// that get's triggered
if (editText.text.isEmpty()) editText.setText(initialValue)
editText.setSelection(editText.text.length) // put cursor at the end
}
// to use it in the summary do something like:
preference?.setOnPreferenceChangeListener { it, newValue ->
it.summary = "updated: $newValue"
true
}
}
此外,在我的 Activity 中扩展 BaseSettingsActivity
我
使用
替换 SharedPreferences
中的管理
preferenceManager.preferenceDataStore = dataStoreCvLogger
有什么方法可以指定android.support.v7.preference.EditTextPreference
的输入法类型吗?
编辑: 以下之前的答案是基于原版 android.preference.EditTextPreference
的,不幸的是不适用于 android.support.v7.preference.EditTextPreference
.
在 android.preference.EditTextPreference
中,EditText
控件以编程方式创建,并且 Preference
中的 AttributeSet
被传递给它。
android.preference.EditTextPreference
Source:
public EditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mEditText = new EditText(context, attrs);
// Give it an ID so it can be saved/restored
mEditText.setId(com.android.internal.R.id.edit);
/*
* The preference framework and view framework both have an 'enabled'
* attribute. Most likely, the 'enabled' specified in this XML is for
* the preference framework, but it was also given to the view framework.
* We reset the enabled state.
*/
mEditText.setEnabled(true);
}
White 允许我们在 Preference
本身上设置 inputType
并将其传递给 EditText
。不幸的是 android.support.v7.preference.EditTextPreference
似乎在 Layout
EditText
有关解决此问题的想法,请参阅 this issue:
Just wanted to let you know that subclassing EditTextPreferenceDialogFragment and overriding onAddEditTextToDialogView as well as overriding PreferenceFragmentCompat#onDisplayPreferenceDialog to show that subclass as needed seems to be working fine, thanks for the help.
创建您自己的 class 扩展 EditTextPreference
并将其设置在那里。
这是我的 EditIntegerPreference
class:
public class EditIntegerPreference extends EditTextPreference {
public EditIntegerPreference(Context context) {
super(context);
}
public EditIntegerPreference(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
public EditIntegerPreference(Context context, AttributeSet attributeSet, int defStyle) {
super(context, attributeSet, defStyle);
getEditText().setInputType(InputType.TYPE_CLASS_NUMBER);
getEditText().setSelectAllOnFocus(true);
}
@Override
public String getText() {
try {
return String.valueOf(getSharedPreferences().getInt(getKey(), 0));
} catch (Exception e) {
return getSharedPreferences().getString(getKey(), "0");
}
}
@Override
public void setText(String text) {
try {
if (getSharedPreferences() != null) {
getSharedPreferences().edit().putInt(getKey(), Integer.parseInt(text)).commit();
}
} catch (Exception e) {
// TODO: This catch stinks!
}
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
getEditText().setInputType(InputType.TYPE_CLASS_NUMBER);
getEditText().setSelectAllOnFocus(true);
if (restoreValue) {
getEditText().setText(getText());
} else {
super.onSetInitialValue(restoreValue, defaultValue != null ? defaultValue : "");
}
}
}
请注意,可以将 inputType
属性添加到 EditTextPreference
android:inputType="number"
我没有走这条路的原因是我希望我的偏好存储为 Integer
而不是 String
现在可以使用 Android-Support-Preference-V7-Fix 库。
修复了 EditTextPreference
将 XML 属性(如 inputType
)转发到 EditText
, 就像最初的偏好一样。
如果您不想使用第三方库,可以为 EditTextPreference 指定布局
<EditTextPreference android:defaultValue="0"
android:key="some_key"
android:title="Title"
android:dialogLayout="@layout/preference_edit_text"/>
然后在res/layout/preference_edit_text.xml
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText android:id="@android:id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:singleLine="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginStart="21dp"
android:layout_marginEnd="21dp"/>
</android.support.constraint.ConstraintLayout>
请注意,编辑文本 ID 必须是:@android:id/edit
但是你可以在 android:inputType
字段
我确定有比使用 21dp
边距更好的对齐 EditText 的方法
但至少它有效
这是我从 Cory Charlton 得到的答案版本,已转移到 Jetpack 首选项并用 Kotlin 编写:
import android.content.Context
import android.content.SharedPreferences
import android.text.InputType
import android.util.AttributeSet
import androidx.preference.EditTextPreference
class EditIntegerPreference : EditTextPreference {
constructor(context: Context?) : super(context) {
setInputMethod()
}
constructor(context: Context?, attributeSet: AttributeSet?) : super(context, attributeSet) {
setInputMethod()
}
constructor(context: Context?, attributeSet: AttributeSet?, defStyle: Int) : super(
context,
attributeSet,
defStyle
) {
setInputMethod()
}
override fun getText(): String =
try {
java.lang.String.valueOf(sharedPreferences.getInt(key, 0))
} catch (e: Exception) {
"0"
}
override fun setText(text: String?) {
try {
if (text != null) {
sharedPreferences?.edit()?.putInt(key, text.toInt())?.apply()
summary = text
} else {
sharedPreferences?.remove(key)
summary = ""
}
} catch (e: Exception) {
sharedPreferences?.remove(key)
summary = ""
}
}
override fun onSetInitialValue(defaultValue: Any?) {
val defaultValueInt: Int =
when (defaultValue){
is Int -> defaultValue
is String -> try {defaultValue.toInt()} catch (ex: java.lang.Exception){0}
else -> 0
}
text = sharedPreferences.getInt(key, defaultValueInt).toString()
}
private fun setInputMethod() {
setOnBindEditTextListener {
it.inputType = InputType.TYPE_CLASS_NUMBER
}
}
fun SharedPreferences.remove(key: String) = edit().remove(key).apply()
}
Kotlin + DataStore + androidx.Preference
的解决方法免责声明!
可能不是这样做的方法!
理想情况下应该只有:
- 将输入设置为 int
- 覆盖
DataStore
class:putInt
/getInt
扩展函数
在我的例子中,我有一个 PreferenceFragmentCompat
,所以:
fun PreferenceFragmentCompat.setNumericInput(
@StringRes prefRes: Int, initialValue: String) {
val preference = findPreference(getString(prefRes)) as EditTextPreference?
preference?.setOnBindEditTextListener { editText ->
editText.inputType = InputType.TYPE_CLASS_NUMBER or
InputType.TYPE_NUMBER_FLAG_SIGNED
// set the initial value: I read it from the DataStore and then
// pass it as the 2nd argument to setNumericInput.
// BTW, I do store stringPreferenceKeys, as it's the putString method
// that get's triggered
if (editText.text.isEmpty()) editText.setText(initialValue)
editText.setSelection(editText.text.length) // put cursor at the end
}
// to use it in the summary do something like:
preference?.setOnPreferenceChangeListener { it, newValue ->
it.summary = "updated: $newValue"
true
}
}
此外,在我的 Activity 中扩展 BaseSettingsActivity
我
使用
SharedPreferences
中的管理
preferenceManager.preferenceDataStore = dataStoreCvLogger