AndroidX前后DialogPreference的区别
Difference between DialogPreference before and after AndroidX
我们目前正在将我们的 Android 应用程序项目迁移到 Androidx 命名空间。但是我注意到不仅名称空间似乎发生了变化。对于 DialogPreference,现在还缺少一些以前使用的接口
- 新接口:https://developer.android.com/reference/androidx/preference/DialogPreference
- 旧界面:https://developer.android.com/reference/kotlin/android/preference/DialogPreference
例如,似乎缺少以下方法:onBindDialogView、showDialog、onDialogClosed。
由于我们使用其中一些方法来影响对话框的默认行为,所以我不清楚现在应该如何实现此功能。例如,我们在关闭对话框之前验证输入,我们将值保存在数据库中而不是共享首选项中,并向对话框添加一些动态元素。
有没有其他人遇到过这个问题并找到了解决方案?我错过了文档中的任何内容吗?我们可以/应该使用另一个概念吗?
可以使用 Fragments 而不是 DialogPreference,但是对于少量内容(例如,用户可以从中选择的树项目列表),这对我来说似乎是一个很大的开销...
从 androidx 源文件开始,我已将基于旧 DialogPreference 的自定义 classes 迁移到新 androidx.preference.DialogPreference 使用以下程序:
第 1 步
基于旧版 DialogPreference 的旧自定义对话框 class(例如 CustomDialogPreference)应拆分为两个单独的 classes:
- 一个 class(例如 CustomPreference)应该扩展 androidx.preference.DialogPreference 并且只包含与偏好处理(数据管理)相关的代码。
- 另一个 class(例如 CustomDialog)应该扩展 androidx.preference.PreferenceDialogFragmentCompat 并且将只包含与对话框处理(用户界面)相关的代码,包括 onDialogClosed。此 class 应将静态方法 newInstance 公开给 return 此 class.
的实例
第 2 步
在基于 PreferenceFragmentCompat 的主要片段处理首选项中,应覆盖 onDisplayPreferenceDialog 方法以显示自定义对话框,例如:
private static final String DIALOG_FRAGMENT_TAG = "CustomPreference";
@Override
public void onDisplayPreferenceDialog(Preference preference) {
if (getParentFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {
return;
}
if (preference instanceof CustomPreference) {
final DialogFragment f = CustomDialog.newInstance(preference.getKey());
f.setTargetFragment(this, 0);
f.show(getParentFragmentManager(), DIALOG_FRAGMENT_TAG);
} else {
super.onDisplayPreferenceDialog(preference);
}
}
对于(像我一样)不完全理解我们应该如何结合 androidx.preference.DialogPreference
和 androidx.preference.PreferenceDialogFragmentCompat
的每个人的小窍门:
第 1 步:
在你的 DialogFragment
的 onAttach()
方法中获取你想要的 SharedPreference
的值(从 newInstance()
方法获取密钥或者只是在里面硬核它)和将其保存为变量。另一方面,在关闭 DialogFragment
之前将新值保存在 SharedPreference
中。通过这样做,您已经创建了 "custom Preference"。
第 2 步:
创建空 androidx.preference.DialogPreference
并在您的 PreferenceScreen
中使用它。然后将它与您的 DialogFragment
结合起来,如@Livio 在第二步中所述:
private static final String DIALOG_FRAGMENT_TAG = "CustomPreference";
@Override
public void onDisplayPreferenceDialog(Preference preference) {
if (getFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {
return;
}
if (preference instanceof CustomPreference) {
final DialogFragment f = CustomDialog.newInstance(preference.getKey());
f.setTargetFragment(this, 0);
f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
} else {
super.onDisplayPreferenceDialog(preference);
}
}
通过这样做,您将获得相同的结果,唯一不同的是您需要在 DialogFragment
.
中自己处理 SharedPreference
您可以使用 AlertDialog
编写您自己的自定义 Preference
,而不是使用 DialogPreference
。
对于那些不想处理 DialogPreference
和 PreferenceDialogFragmentCompat
.
的人来说,这可能是一种解决方法
import android.content.Context;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
public class CustomDialogPreference extends Preference {
private final Context context;
public CustomDialogPreference(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
@Override
protected void onClick() { //what happens when clicked on the preference
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("TITLE")
.setMessage("message")
.setPositiveButton("OK", (dialog, which) -> {
String preferenceKey = getKey(); //You can update the SharedPreference with the key
//....
})
.setNegativeButton("CANCEL", (dialog, which) -> {
//....
})
.create().show();
}
}
onClick()
和getKey()
方法属于Preference
class。 context
对象自带构造函数等等..
密钥可以像其他首选项一样在 xml 文件中或以编程方式在 PreferenceFragment 中定义。
<com.myApp.CustomDialogPreference
android:key="my_preference_key"
android:summary="..."
android:title="..." />
我们目前正在将我们的 Android 应用程序项目迁移到 Androidx 命名空间。但是我注意到不仅名称空间似乎发生了变化。对于 DialogPreference,现在还缺少一些以前使用的接口
- 新接口:https://developer.android.com/reference/androidx/preference/DialogPreference
- 旧界面:https://developer.android.com/reference/kotlin/android/preference/DialogPreference
例如,似乎缺少以下方法:onBindDialogView、showDialog、onDialogClosed。
由于我们使用其中一些方法来影响对话框的默认行为,所以我不清楚现在应该如何实现此功能。例如,我们在关闭对话框之前验证输入,我们将值保存在数据库中而不是共享首选项中,并向对话框添加一些动态元素。
有没有其他人遇到过这个问题并找到了解决方案?我错过了文档中的任何内容吗?我们可以/应该使用另一个概念吗?
可以使用 Fragments 而不是 DialogPreference,但是对于少量内容(例如,用户可以从中选择的树项目列表),这对我来说似乎是一个很大的开销...
从 androidx 源文件开始,我已将基于旧 DialogPreference 的自定义 classes 迁移到新 androidx.preference.DialogPreference 使用以下程序:
第 1 步
基于旧版 DialogPreference 的旧自定义对话框 class(例如 CustomDialogPreference)应拆分为两个单独的 classes:
- 一个 class(例如 CustomPreference)应该扩展 androidx.preference.DialogPreference 并且只包含与偏好处理(数据管理)相关的代码。
- 另一个 class(例如 CustomDialog)应该扩展 androidx.preference.PreferenceDialogFragmentCompat 并且将只包含与对话框处理(用户界面)相关的代码,包括 onDialogClosed。此 class 应将静态方法 newInstance 公开给 return 此 class. 的实例
第 2 步
在基于 PreferenceFragmentCompat 的主要片段处理首选项中,应覆盖 onDisplayPreferenceDialog 方法以显示自定义对话框,例如:
private static final String DIALOG_FRAGMENT_TAG = "CustomPreference";
@Override
public void onDisplayPreferenceDialog(Preference preference) {
if (getParentFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {
return;
}
if (preference instanceof CustomPreference) {
final DialogFragment f = CustomDialog.newInstance(preference.getKey());
f.setTargetFragment(this, 0);
f.show(getParentFragmentManager(), DIALOG_FRAGMENT_TAG);
} else {
super.onDisplayPreferenceDialog(preference);
}
}
对于(像我一样)不完全理解我们应该如何结合 androidx.preference.DialogPreference
和 androidx.preference.PreferenceDialogFragmentCompat
的每个人的小窍门:
第 1 步:
在你的 DialogFragment
的 onAttach()
方法中获取你想要的 SharedPreference
的值(从 newInstance()
方法获取密钥或者只是在里面硬核它)和将其保存为变量。另一方面,在关闭 DialogFragment
之前将新值保存在 SharedPreference
中。通过这样做,您已经创建了 "custom Preference"。
第 2 步:
创建空 androidx.preference.DialogPreference
并在您的 PreferenceScreen
中使用它。然后将它与您的 DialogFragment
结合起来,如@Livio 在第二步中所述:
private static final String DIALOG_FRAGMENT_TAG = "CustomPreference";
@Override
public void onDisplayPreferenceDialog(Preference preference) {
if (getFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {
return;
}
if (preference instanceof CustomPreference) {
final DialogFragment f = CustomDialog.newInstance(preference.getKey());
f.setTargetFragment(this, 0);
f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
} else {
super.onDisplayPreferenceDialog(preference);
}
}
通过这样做,您将获得相同的结果,唯一不同的是您需要在 DialogFragment
.
SharedPreference
您可以使用 AlertDialog
编写您自己的自定义 Preference
,而不是使用 DialogPreference
。
对于那些不想处理 DialogPreference
和 PreferenceDialogFragmentCompat
.
import android.content.Context;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
public class CustomDialogPreference extends Preference {
private final Context context;
public CustomDialogPreference(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
@Override
protected void onClick() { //what happens when clicked on the preference
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("TITLE")
.setMessage("message")
.setPositiveButton("OK", (dialog, which) -> {
String preferenceKey = getKey(); //You can update the SharedPreference with the key
//....
})
.setNegativeButton("CANCEL", (dialog, which) -> {
//....
})
.create().show();
}
}
onClick()
和getKey()
方法属于Preference
class。 context
对象自带构造函数等等..
密钥可以像其他首选项一样在 xml 文件中或以编程方式在 PreferenceFragment 中定义。
<com.myApp.CustomDialogPreference
android:key="my_preference_key"
android:summary="..."
android:title="..." />