AndroidX:设置 Enter 键以验证 EditTextPreference 对话框
AndroidX: Set Enter key to validate EditTextPreference dialog box
我正在尝试使用 AndroidX 创建首选项屏幕,但我遇到了一个小问题...
当我使用虚拟键盘上的 "OK" 按钮验证我的输入时,首选项未被验证。 (键盘被隐藏了,仅此而已...)
使用 AndroidX,我们无法再覆盖 EditTextPreference
中的 showDialog()
...而且我找不到另一种方法来访问对话框以关闭它。
总而言之,我希望:虚拟键盘上按钮的 DONE 操作验证 AlertDialog。
这是我的示例代码:
XML 文件
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
<EditTextPreference
app:key="pref_1"
app:title="Test"
app:useSimpleSummaryProvider="true" />
</PreferenceScreen>
偏好activity
public class MySettingsActivity extends AppCompatActivity implements
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
[...]
public static class HeaderFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.header_preferences, rootKey);
EditTextPreference pref1 = getPreferenceManager().findPreference("pref_1");
pref1.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
@Override
public void onBindEditText(@NonNull EditText editText) {
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
}
});
}
}
}
如果你想验证文本的更新值,你需要使用这个监听器
pref1.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// put validation here..
Log.d("Prefrence====>",newValue+"<=== validate you can validate this value");
return true; //if you pass false here the updated value will not save
}
});
这里是使用真假的例子return
public static class HeaderFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.headerpref, rootKey);
EditTextPreference pref1 = getPreferenceManager().findPreference("pref_1");
pref1.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// put validation here..
Log.d("Prefrence====>",newValue+"<=== validate you can validate this value");
if(newValue.toString().length()>0){
return true;
}else return false;
}
});
pref1.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
@Override
public void onBindEditText(@NonNull EditText editText) {
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
//Your dialog will dissmiss on ok click
if(actionId==EditorInfo.IME_ACTION_DONE)dismissDialog();
return false;
}
});
}
});
}
void dismissDialog(){
for(Fragment fragments : HeaderFragment.this.getActivity().getSupportFragmentManager().getFragments()){
if(fragments instanceof EditTextPreferenceDialogFragmentCompat){
EditTextPreferenceDialogFragmentCompat dialog = ((EditTextPreferenceDialogFragmentCompat) fragments);
dialog.onDialogClosed(true);
dialog.dismiss();
return;
}
}
}
}
既然你想手动关闭对话框,你可以这样做,因为没有直接的方法可以获取对话框并关闭它。
我更新了对话框关闭侦听器,因为您需要保存在 onDialogClosed 方法中传递 true 的数据将有助于保存您的数据
void dismissDialog(){
for(Fragment fragments : HeaderFragment.this.getActivity().getSupportFragmentManager().getFragments()){
if(fragments instanceof EditTextPreferenceDialogFragmentCompat){
EditTextPreferenceDialogFragmentCompat dialog = ((EditTextPreferenceDialogFragmentCompat) fragments);
dialog.onDialogClosed(true);
dialog.dismiss();
return;
}
}
}
我找到了另一种方法。我不认为它是最好的,但如果它可以帮助任何人...
PreferenceFragmentCompat 自定义
public class PreferenceFragmentCompatCustom extends PreferenceFragmentCompat {
private static final String DIALOG_FRAGMENT_TAG =
"androidx.preference.PreferenceFragment.DIALOG";
private DialogFragment mDialogFragment;
@Override
public void onDisplayPreferenceDialog(Preference preference) {
if (getActivity() instanceof MySettingsActivity) {
final DialogFragment f;
if (preference instanceof EditTextPreference) {
f = EditTextPreferenceDialogFragmentCompat.newInstance(preference.getKey());
} else if (preference instanceof ListPreference) {
f = ListPreferenceDialogFragmentCompat.newInstance(preference.getKey());
} else {
throw new IllegalArgumentException("Tried to display dialog for unknown " +
"preference type. Did you forget to override onDisplayPreferenceDialog()?");
}
f.setTargetFragment(this, 0);
// Expose the dialog
mDialogFragment = f;
f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
}else{
super.onDisplayPreferenceDialog(preference);
}
}
public DialogFragment getDialog(){ return mDialogFragment;}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {}
}
偏好activity
public class MySettingsActivity extends AppCompatActivity implements
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
[...]
public static class HeaderFragment extends PreferenceFragmentCompatCustom {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.header_preferences, rootKey);
EditTextPreference pref1 = getPreferenceManager().findPreference("pref_1");
pref1.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
@Override
public void onBindEditText(@NonNull EditText editText) {
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
// If callOnClick, do not save value here
//etpTest.setText(v.getText().toString());
// If dismiss, the preference is not set !
//getDialog().dismiss();
((AlertDialog) getDialog().getDialog())
.getButton(DialogInterface.BUTTON_POSITIVE)
.callOnClick();
return true;
}
return false;
}
});
}
});
}
}
}
我正在尝试使用 AndroidX 创建首选项屏幕,但我遇到了一个小问题...
当我使用虚拟键盘上的 "OK" 按钮验证我的输入时,首选项未被验证。 (键盘被隐藏了,仅此而已...)
使用 AndroidX,我们无法再覆盖 EditTextPreference
中的 showDialog()
...而且我找不到另一种方法来访问对话框以关闭它。
总而言之,我希望:虚拟键盘上按钮的 DONE 操作验证 AlertDialog。
这是我的示例代码:
XML 文件
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
<EditTextPreference
app:key="pref_1"
app:title="Test"
app:useSimpleSummaryProvider="true" />
</PreferenceScreen>
偏好activity
public class MySettingsActivity extends AppCompatActivity implements
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
[...]
public static class HeaderFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.header_preferences, rootKey);
EditTextPreference pref1 = getPreferenceManager().findPreference("pref_1");
pref1.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
@Override
public void onBindEditText(@NonNull EditText editText) {
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
}
});
}
}
}
如果你想验证文本的更新值,你需要使用这个监听器
pref1.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// put validation here..
Log.d("Prefrence====>",newValue+"<=== validate you can validate this value");
return true; //if you pass false here the updated value will not save
}
});
这里是使用真假的例子return
public static class HeaderFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.headerpref, rootKey);
EditTextPreference pref1 = getPreferenceManager().findPreference("pref_1");
pref1.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// put validation here..
Log.d("Prefrence====>",newValue+"<=== validate you can validate this value");
if(newValue.toString().length()>0){
return true;
}else return false;
}
});
pref1.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
@Override
public void onBindEditText(@NonNull EditText editText) {
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
//Your dialog will dissmiss on ok click
if(actionId==EditorInfo.IME_ACTION_DONE)dismissDialog();
return false;
}
});
}
});
}
void dismissDialog(){
for(Fragment fragments : HeaderFragment.this.getActivity().getSupportFragmentManager().getFragments()){
if(fragments instanceof EditTextPreferenceDialogFragmentCompat){
EditTextPreferenceDialogFragmentCompat dialog = ((EditTextPreferenceDialogFragmentCompat) fragments);
dialog.onDialogClosed(true);
dialog.dismiss();
return;
}
}
}
}
既然你想手动关闭对话框,你可以这样做,因为没有直接的方法可以获取对话框并关闭它。
我更新了对话框关闭侦听器,因为您需要保存在 onDialogClosed 方法中传递 true 的数据将有助于保存您的数据
void dismissDialog(){
for(Fragment fragments : HeaderFragment.this.getActivity().getSupportFragmentManager().getFragments()){
if(fragments instanceof EditTextPreferenceDialogFragmentCompat){
EditTextPreferenceDialogFragmentCompat dialog = ((EditTextPreferenceDialogFragmentCompat) fragments);
dialog.onDialogClosed(true);
dialog.dismiss();
return;
}
}
}
我找到了另一种方法。我不认为它是最好的,但如果它可以帮助任何人...
PreferenceFragmentCompat 自定义
public class PreferenceFragmentCompatCustom extends PreferenceFragmentCompat {
private static final String DIALOG_FRAGMENT_TAG =
"androidx.preference.PreferenceFragment.DIALOG";
private DialogFragment mDialogFragment;
@Override
public void onDisplayPreferenceDialog(Preference preference) {
if (getActivity() instanceof MySettingsActivity) {
final DialogFragment f;
if (preference instanceof EditTextPreference) {
f = EditTextPreferenceDialogFragmentCompat.newInstance(preference.getKey());
} else if (preference instanceof ListPreference) {
f = ListPreferenceDialogFragmentCompat.newInstance(preference.getKey());
} else {
throw new IllegalArgumentException("Tried to display dialog for unknown " +
"preference type. Did you forget to override onDisplayPreferenceDialog()?");
}
f.setTargetFragment(this, 0);
// Expose the dialog
mDialogFragment = f;
f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
}else{
super.onDisplayPreferenceDialog(preference);
}
}
public DialogFragment getDialog(){ return mDialogFragment;}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {}
}
偏好activity
public class MySettingsActivity extends AppCompatActivity implements
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
[...]
public static class HeaderFragment extends PreferenceFragmentCompatCustom {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.header_preferences, rootKey);
EditTextPreference pref1 = getPreferenceManager().findPreference("pref_1");
pref1.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
@Override
public void onBindEditText(@NonNull EditText editText) {
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
// If callOnClick, do not save value here
//etpTest.setText(v.getText().toString());
// If dismiss, the preference is not set !
//getDialog().dismiss();
((AlertDialog) getDialog().getDialog())
.getButton(DialogInterface.BUTTON_POSITIVE)
.callOnClick();
return true;
}
return false;
}
});
}
});
}
}
}