【问题标题】:Android support EditTextPreference input typeAndroid 支持 EditTextPreference 输入类型
【发布时间】:2016-04-26 16:29:50
【问题描述】:

有没有办法指定android.support.v7.preference.EditTextPreference的输入法类型?

【问题讨论】:

标签: android android-support-library edittextpreference


【解决方案1】:

如果不想使用第三方库,可以给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 字段中随意使用任何你想要的东西

我确信有更好的方法来对齐 EditText 而不是使用21dp 边距 但至少它有效

【讨论】:

  • 非常感谢。接受的答案提供使用 3rd 方库。更重要的是,它实际上不是针对 android-support 库,而是针对 androidX,这在我的情况下是不可接受的。
【解决方案2】:

现在可以使用Android-Support-Preference-V7-Fix 库。
修复了EditTextPreference 将XML 属性(如inputType)转发到EditText,就像原来的偏好一样。

【讨论】:

  • 这个库远远优于 android.support.v7.preference。功能更丰富,主题更容易。
  • AndroidX 有一个setOnBindEditTextListener 方法可以用来解决这个问题。您可以从侦听器中更改 EditText 输入类型。见developer.android.com/reference/androidx/preference/…
【解决方案3】:

这是我的 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()
 }

【讨论】:

  • 如果使用PreferenceDatastore 会怎样?然后我们如何将上述内容绑定到自定义DataStore
【解决方案4】:

编辑:以下之前的答案是基于股票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

只是想让您知道,子类化 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

【讨论】:

  • 很遗憾android.support.v7.preference.EditTextPreference 不包含getEditText() 方法。
  • @ivkil 您需要android.support.v7.preference.EditTextPreference 有什么特别的原因吗?我问是因为android.preference.EditTextPreference 从 API 级别 1 开始就已经存在。
  • 是的。为了为我的应用提供设置,我使用PreferenceFragmentCompat
  • @ivkil 可惜我还没用过PreferenceFragmentCompat。不知道为什么支持实现是股票Preference 的回归。我看看能不能找到别的东西。
  • @ivkil 我用可能的解决方案更新了我的答案,尽管涉及更多。
【解决方案5】:

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 

【讨论】:

    猜你喜欢
    • 2021-05-26
    • 2021-12-01
    • 2022-01-15
    • 2020-07-21
    • 2018-09-24
    • 2020-09-29
    • 2020-06-24
    • 2023-03-30
    • 2022-11-11
    相关资源
    最近更新 更多