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中的首选项键,并监听您的首选项更改?请参阅更新的答案。这很有效!美好的我确实意识到,这仍然有一个障碍,那就是完全干净的解决方案——中间活动必须在使用它的每个项目中注册。但至少现在它只是一行代码。你不应该在每个项目中都注册它-如果你在库的清单中定义它,清单合并应该在消费应用程序的最终清单中包括它: