Поддержка Android EditTextPreference тип ввода

Есть ли способ указать тип метода ввода для android.support.v7.preference.EditTextPreference?

5 ответов

Решение

Теперь можно использовать библиотеку https://github.com/Gericop/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>

Обратите внимание, что идентификатор редактируемого текста должен быть: @android:id/editно тогда вы можете использовать все, что вы хотите внутри android:inputType поле

Я уверен, что есть лучший способ выровнять EditText, чем использовать 21dp поля, но по крайней мере это работает

Вот моя версия ответа Кори Чарльтона, перенесенная в настройки 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()
 }

Изменить: предыдущие ответы ниже были построены на складе android.preference.EditTextPreference и, к сожалению, не работают на android.support.v7.preference.EditTextPreference,

в android.preference.EditTextPreference EditText управление создается программно и AttributeSet от Preference передается к нему.

android.preference.EditTextPreference Источник:

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);
}

Белый позволяет нам установить inputType на Preference само по себе и сделать это до EditText, К сожалению android.support.v7.preference.EditTextPreference кажется, чтобы создать EditText в Layout

Посмотрите эту проблему для идей обойти это:

Просто хотел сообщить, что создание подкласса EditTextPreferenceDialogFragment и переопределение onAddEditTextToDialogView, а также переопределение PreferenceFragmentCompat#onDisplayPreferenceDialog, чтобы показать, что подкласс по мере необходимости, работает нормально, спасибо за помощь.


Создайте свой собственный класс, который расширяет EditTextPreference и установить его там.

Вот мой EditIntegerPreference учебный класс:

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

Обходной путь для Kotlin + DataStore + androidx.Preference

Отказ от ответственности!

Вероятно, это не способ сделать это!
В идеале следует только:

  • установите для ввода значение int
  • отменить в DataStoreучебный класс: 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
  }
}

Кроме того, в моей деятельности, которая распространяется BaseSettingsActivityЯ заменяю управление из SharedPreferencesс использованием:

      preferenceManager.preferenceDataStore = dataStoreCvLogger 
Другие вопросы по тегам