AndroidX之前和之后DialogPreference之间的区别

时间:2018-10-11 07:32:30

标签: android androidx

我们当前正在通过我们的Android应用程序项目迁移到Androidx命名空间。但是我注意到不仅名称空间似乎已更改。对于DialogPreference,现在也缺少以前使用的一些接口

例如,似乎缺少以下方法:onBindDialogView,showDialog,onDialogClosed。

由于我们使用了其中一些方法来影响对话框的默认行为,因此我不清楚现在应如何实现此功能。例如,我们在关闭对话框之前验证输入,将值保存在数据库中而不是sharedpreferences中,并向对话框中添加一些动态元素。

其他人是否已经遇到此问题并找到了解决方案?我错过了文档中的任何内容吗?我们可以/应该使用另一个概念吗?

可以使用Fragments而不是DialogPreference,但是对于少量内容(例如,用户可以从中选择的树项目列表)来说,这似乎给我带来了很多开销...

3 个答案:

答案 0 :(得分:7)

从androidx源文件开始,我已按照以下步骤将基于旧 DialogPreference 的自定义类迁移到了新的 androidx.preference.DialogPreference 中:

步骤1

基于旧DialogPreference的旧的自定义对话框类(例如CustomDialogPreference)应分为两个单独的类:

  1. 一个类(例如CustomPreference)应该扩展 androidx.preference.DialogPreference ,并且仅包含与偏好设置(数据管理)相关的代码。
  2. 另一个类(例如CustomDialog)应扩展 androidx.preference.PreferenceDialogFragmentCompat ,并且仅包含与对话框处理(用户界面)相关的代码,包括 onDialogClosed 。此类应公开一个静态方法 newInstance 以返回此类的实例。

步骤2

在基于 PreferenceFragmentCompat 的主要片段处理首选项中,应覆盖 onDisplayPreferenceDialog 方法以显示自定义对话框,例如:

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

答案 1 :(得分:1)

对于每个不完全了解我们应该如何结合androidx.preference.DialogPreferenceandroidx.preference.PreferenceDialogFragmentCompat的人(比如我)来说,都是一个小技巧:

步骤1:

在您的DialogFragment的{​​{1}}方法中,获取所需的onAttach()的值(从SharedPreference方法中获取密钥,或者仅在内部对其进行硬核化)并将其保存作为变量。另一方面,在关闭newInstance()之前,将新值保存在SharedPreference中。这样,您就创建了“自定义首选项”。

第2步:

创建空的DialogFragment,并在androidx.preference.DialogPreference中使用它。然后将其与您的PreferenceScreen结合使用,如@Livio的第二步所述:

DialogFragment

这样做,您将获得与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); } } 内的SharedPreference自己相同的结果,只是区别。

答案 2 :(得分:0)

您可以使用 DialogPreference 编写自己的自定义 Preference,而不是使用 AlertDialog。 对于不想处理 DialogPreferencePreferenceDialogFragmentCompat 的人来说,这可能是一种解决方法。

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 类。 context 对象带有构造函数等等..

可以在 xml 文件中或以编程方式在 PreferenceFragment 中将密钥定义为其他首选项。

<com.myApp.CustomDialogPreference
    android:key="my_preference_key"
    android:summary="..."
    android:title="..." />