Android - 使用Preference Support Library中的EditTextPreference类没有getEditText方法

9
我刚刚不得不改用PreferenceFragmentCompat来实现权限检查,这意味着使用EditTextPreference的支持版本。不幸的是,似乎getEditText方法已经消失了。有什么解决方法吗?
更新: 发现这个问题已被记录在issue中。看起来它已经被故意删除了,但答案没有解释如何实现我想要做的事情。
我之前使用的代码如下:
final EditText editTextTL;
editTextTL = ((EditTextPreference) findPreference("my_preference")).getEditText();
editTextTL.setFilters(new InputFilter[]{new NumericRangeFilter()});
editTextTL.setOnFocusChangeListener(new AmountOnFocusChangeListener());

我的相关导入

import android.support.v7.preference.EditTextPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceFragmentCompat;

我的Gradle依赖项

compile 'com.android.support:support-v4:23.0.1'
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:preference-v14:23.0.1'
compile 'com.android.support:recyclerview-v7:23.0.1'

1
如果你想使用更强大的解决方案(即使用XML设置属性而不是从代码中设置),我建议你看一下我的解决方案中“有趣的事情”部分:https://github.com/Gericop/Android-Support-Preference-V7-Fix - Gergely Kőrössy
谢谢提供链接,我需要做一些仅靠属性无法应对的事情,但样式元素将会很有用。这个支持库有多少问题啊,真是惊人。 - CodeChimp
5个回答

2

使用 AndroidX preference 库,setOnBindEditTextListener(...),该监听器实现会给出 EditText 元素,您可以根据需要自定义 EditText。


2
创建自定义EditTextPreference:
public class CustomEditTextPreference extends EditTextPreference {
    public CustomEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr,
        int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
    public CustomEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    public CustomEditTextPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public CustomEditTextPreference(Context context) {
        super(context);
    }
}

在xml文件中声明它以供首选项使用:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <com.example.CustomEditTextPreference
        android:key="test_key"
        android:title="Title" />
</PreferenceScreen>

请使用以下代码更新您的PreferenceFragmentCompat:

public class PrefFragment extends PreferenceFragmentCompat {

private static final String DIALOG_FRAGMENT_TAG =
    "android.support.v7.preference.PreferenceFragment.DIALOG";

@Override
public void onCreatePreferences(Bundle bundle, String s) {
    addPreferencesFromResource(R.xml.settings);
}

@Override
public void onDisplayPreferenceDialog(Preference preference) {
    // check if dialog is already showing
    if (getFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {
        return;
    }

    DialogFragment f = null;
    if (preference instanceof CustomEditTextPreference) {
        f = EditTextPreferenceDialog.newInstance(preference.getKey());
    } else {
        super.onDisplayPreferenceDialog(preference);
    }
    if (f != null) {
        f.setTargetFragment(this, 0);
        f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
    }
}

public static class EditTextPreferenceDialog extends EditTextPreferenceDialogFragmentCompat {

    public static EditTextPreferenceDialog newInstance(String key) {
        final EditTextPreferenceDialog
            fragment = new EditTextPreferenceDialog();
        final Bundle b = new Bundle(1);
        b.putString(ARG_KEY, key);
        fragment.setArguments(b);
        return fragment;
    }

    @Override
    protected void onBindDialogView(View view) {
        super.onBindDialogView(view);
        ((EditText)view.findViewById(android.R.id.edit)).setFilters(new InputFilter[]{new NumericRangeFilter()});
    }

}

}


1
在Preference Support Lib中,EditTextPreference上也没有getDialog方法,我自己也在考虑类似的解决方案。 - CodeChimp
我已经实现了这个功能,并且在调试时可以看到init和onFocusChange被调用。但是当按下OK时,它并没有从首选项中获取值或设置值,因此我的摘要/持久化首选项没有更新。肯定还需要实现其他东西,但不确定是什么。 - CodeChimp
@CodeChimp,我更新了代码。希望它能对你有用。我研究了Android的内部并改变了方法。虽然不是很好的解决方案,但对我来说有效。 - Ilya Tretyakov
这对我很有效。非常感谢您为我彻底调查此事。仅仅因为要从支持库中删除一个简单的方法,真是一团糟! - CodeChimp

0

2021: 答案

为了更改EditText的值或属性,您需要根据新的AndroidX Kotlin设置setOnBindEditTextListener回调。

findPreference<EditTextPreference>("key")?.setOnBindEditTextListener {
    it.filters = arrayOf<InputFilter>(InputFilter.AllCaps())
}

0
也许这会有所帮助,我今天在处理这个问题时遇到了困难,但是我基于片段找到了解决方案。这段代码适用于 EditTextPreference 点击后,假设首选项对话框已显示。
List<Fragment> fragments = getSupportFragmentManager().getFragments();
Fragment dialogFragment = null;
boolean dialogFragmentFound = false;
for (Fragment f : fragments) {
    if (f != null) {
        String tag = f.getTag();
        if (tag != null) {
            tag = tag.toLowerCase().trim();
            if (tag.indexOf("preference") >= 0 && tag.indexOf("dialog") >= 0) {
                dialogFragmentFound = true;
                dialogFragment = f;
            }
        }
    }
}
if (dialogFragmentFound) {
    Dialog dialog = ((DialogFragment) dialogFragment).getDialog();
    EditText ediText = dialog.findViewById(android.R.id.edit);
    if (ediText != null)
        ediText.setText("your text");
}

致以最好的祝福


-2

我看到这个库正在使用android.support.v7.widget.AppCompatEditText; 但是PreferenceFragmentCompat中的findPreference无法转换为该类型。 我正在使用com.android.support:preference-v14:23.0.1。 - CodeChimp
5
这不是官方支持库。 - Gergely Kőrössy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接