Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/202.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 可侦听首选项值更改的自定义首选项_Android_Sharedpreferences - Fatal编程技术网

Android 可侦听首选项值更改的自定义首选项

Android 可侦听首选项值更改的自定义首选项,android,sharedpreferences,Android,Sharedpreferences,我正在创建一个自定义首选项,允许用户从库中选择图像。为此,我将其意图设置为启动一个中间半透明活动,该活动反过来启动一个包含ACTION\u GET\u CONTENT的活动,并在startActivityForResult中持久化用户所选内容的URI (事实上,我用一个常量名将文件保存到内存中,并用时间戳保存一个长文件,但我认为这与我的问题无关。) 现在我想用新选择的图像更新我在Preference子类的setWidget空间中使用的ImageView。自定义首选项类如何侦听对其自己的首选项值的

我正在创建一个自定义首选项,允许用户从库中选择图像。为此,我将其意图设置为启动一个中间半透明活动,该活动反过来启动一个包含
ACTION\u GET\u CONTENT
的活动,并在
startActivityForResult
中持久化用户所选内容的URI

(事实上,我用一个常量名将文件保存到内存中,并用时间戳保存一个长文件,但我认为这与我的问题无关。)

现在我想用新选择的图像更新我在Preference子类的
setWidget
空间中使用的ImageView。自定义首选项类如何侦听对其自己的首选项值的更改

我在
onBindView()
中设置图像时没有问题,但这仅在设置首选项屏幕时调用。我已经查看了各种内置首选项的来源,但没有一个有这个问题,因为没有一个打开了进行首选项选择的活动。它们都有一个对话框,可以回调首选项,或者使用
onClick()
在内部执行操作

但是,我想不出一种方法可以让用户在不使用
ACTION\u get\u CONTENT
活动的情况下选择画廊图像

我知道我可以添加一个公共方法,然后在我的首选项活动中使用OnSharedPreferenceChangedListener手动回调首选项以更新自身。但是我想把这个类放在一个库中,以便在多个项目中使用(以后可能会在一个开源库中发布),因此需要所有这些手动步骤是非常难看的。

你检查过了吗?这将启动铃声选择器活动,并通过将自身注册为
首选项管理器来处理结果。OnActivityResultListener
侦听器,因此它将被所属活动委派

选择源代码中的代码段:

@Override
protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
    super.onAttachedToHierarchy(preferenceManager);

    preferenceManager.registerOnActivityResultListener(this);
    mRequestCode = preferenceManager.getNextRequestCode();
}

public boolean onActivityResult(int requestCode, int resultCode, Intent data) {

    if (requestCode == mRequestCode) {

        if (data != null) {
            Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);

            if (callChangeListener(uri != null ? uri.toString() : "")) {
                onSaveRingtone(uri);
            }
        }

        return true;
    }

    return false;
}
编辑:


然后,您的活动将更新活动结果中的首选项:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    SharedPreferences preferences = getSharedPreferences("Name of shared preferences", MODE_PRIVATE);
    // OR use default
    // SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
    preferences.edit().putString("custom_preference_key", "VALUE").apply();
}
你查过了吗?这将启动铃声选择器活动,并通过将自身注册为
首选项管理器来处理结果。OnActivityResultListener
侦听器,因此它将被所属活动委派

选择源代码中的代码段:

@Override
protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
    super.onAttachedToHierarchy(preferenceManager);

    preferenceManager.registerOnActivityResultListener(this);
    mRequestCode = preferenceManager.getNextRequestCode();
}

public boolean onActivityResult(int requestCode, int resultCode, Intent data) {

    if (requestCode == mRequestCode) {

        if (data != null) {
            Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);

            if (callChangeListener(uri != null ? uri.toString() : "")) {
                onSaveRingtone(uri);
            }
        }

        return true;
    }

    return false;
}
编辑:


然后,您的活动将更新活动结果中的首选项:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    SharedPreferences preferences = getSharedPreferences("Name of shared preferences", MODE_PRIVATE);
    // OR use default
    // SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
    preferences.edit().putString("custom_preference_key", "VALUE").apply();
}

我忽略了铃声参考。但仍然无法让它在我的班级内部运行。PreferenceManager的
getActivity()
/
getFragment()
受包保护。因此,我可以设置首选项的意图,但由于首选项不知道它属于哪个活动,因此它无法调用
startActivityForResult()
。啊,对不起,我没有意识到这些方法是包私有的。您是否可以更新ActivityResult中的首选项键,并监听您的首选项更改?请参阅更新的答案。这很有效!美好的我确实意识到,这仍然有一个障碍,那就是完全干净的解决方案——中间活动必须在使用它的每个项目中注册。但至少现在它只是一行代码。你不应该在每个项目中都注册它-如果你在库的清单中定义它,清单合并应该在消费应用程序的最终清单中包括它:我忽略了RingtonePreference。但仍然无法让它在我的班级内部运行。PreferenceManager的
getActivity()
/
getFragment()
受包保护。因此,我可以设置首选项的意图,但由于首选项不知道它属于哪个活动,因此它无法调用
startActivityForResult()
。啊,对不起,我没有意识到这些方法是包私有的。您是否可以更新ActivityResult中的首选项键,并监听您的首选项更改?请参阅更新的答案。这很有效!美好的我确实意识到,这仍然有一个障碍,那就是完全干净的解决方案——中间活动必须在使用它的每个项目中注册。但至少现在它只是一行代码。你不应该在每个项目中都注册它-如果你在库的清单中定义它,清单合并应该在消费应用程序的最终清单中包括它: