[英]Android SharedPreferences/PreferenceFragment not working
[英]Android - SharedPreferences ListPreference - PreferenceFragment onCreate not called
好的,我知道之前有很多关于Android中的SharedPreferences的问题,我确实做到了很多,但是由于我对SharedPreferences有点陌生,所以我不知道如何使其正常工作的最后几步。
在我的MainActivity中,我有以下内容:
public class MainActivity extends ActionBarActivity
{
...
// Public static MainActivity so we can use findViewById from MyPrefsActivity
public static MainActivity mActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
mActivity = this;
}
...
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch(id){
case R.id.action_settings:
startActivity(new Intent(this, MyPrefsActivity.class));
return true;
}
return false;
}
}
这是MyPrefsActivity.java:
package com.example.checkboxoptionsv2;
import android.annotation.TargetApi;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.ImageButton;
public class MyPrefsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener
{
private static int prefs = R.xml.settings;
private ImageButton cbButton, spinnerButton, popupButton;
private final String LIST_PREFERENCE = "prefCheckboxOption";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try{
getClass().getMethod("getFragmentManager");
AddResourceApi11AndGreater();
}
catch(NoSuchMethodException e){ // Android API < 11
AddResourceApiLessThan11();
}
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
preferences.registerOnSharedPreferenceChangeListener(this);
* ListPreference listPreference = (ListPreference) findPreference(LIST_PREFERENCE);
if(listPreference.getValue() == null)
listPreference.setValue("0");
cbButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnCheckbox);
spinnerButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnSpinner);
popupButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnPopup);
setChosenPreference(0);
}
private void setChosenPreference(int chosen_value){
// First put all Visibilities on GONE
cbButton.setVisibility(View.GONE);
spinnerButton.setVisibility(View.GONE);
popupButton.setVisibility(View.GONE);
// Then turn the chosen on VISIBLE again
switch(chosen_value){
case 0: // Multi-Click CheckBox
default:
cbButton.setVisibility(View.VISIBLE);
break;
case 1: // Dropdown CheckBox
spinnerButton.setVisibility(View.VISIBLE);
break;
case 2: // Pop-up CheckBox
popupButton.setVisibility(View.VISIBLE);
break;
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(key.equals(LIST_PREFERENCE)){
ListPreference listPreference = (ListPreference) findPreference(key); // LIST_PREFERENCE
listPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
int chosen_option = Integer.valueOf((String) newValue);
setChosenPreference(chosen_option);
return false;
}
});
}
else{
// Other settings
}
}
@SuppressWarnings("deprecation")
protected void AddResourceApiLessThan11(){
addPreferencesFromResource(prefs);
}
@TargetApi(11)
protected void AddResourceApi11AndGreater(){
* MyPreferenceFragment pf = new MyPreferenceFragment();
getFragmentManager().beginTransaction().replace(android.R.id.content, pf).commit();
}
@TargetApi(11)
public static class MyPreferenceFragment extends PreferenceFragment{
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
* addPreferencesFromResource(MyPrefsActivity.prefs); // outer class
// private members seem to be visible for inner class, and
// making it static made things so much easier
}
}
}
以及settings.xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="@string/checkbox_options_title" >
<ListPreference
android:key="prefCheckboxOption"
android:title="@string/pref_checkbox_option"
android:summary="@string/checkbox_options_summary"
android:entries="@array/checkbox_options"
android:entryValues="@array/checkbox_option_values" />
</PreferenceCategory>
</PreferenceScreen>
和arrays.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="checkbox_options">
<item>CheckBox as Multi-Click</item>
<item>CheckBox as Dropdown</item>
<item>CheckBox as Pop-up</item>
</string-array>
<string-array name="checkbox_option_values">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
</resources>
(当然,我还将MyPrefsActivity包含在AndroidManifest.xml中)
我的目标是根据ListPreference中选择的首选项,使三个复选框选项(在setChosenPreference方法中找到)之一变为可见,而另两个变为GONE。
现在,onCreate()方法和onSharedPreferenceChanged()中的Listpreference为null,并给出NullPointerException。 因此,我设置了一些断点(请参见三个“ *”),它们为空的原因是因为未调用第三个“ *”(在静态类PF中)。
应该在使用findPreference之前调用addPreferencesFromResources,否则它将返回null。 有谁知道为什么在调试过程中我确实到达了AddResourceApi11AndGreater()方法中的第二个“ *”,但是却没有到达MyPreferenceFragment-class onCreate method()中的第三个“ *”?.. onCreate没有被调用完全没有。
另外,我的其余代码看起来还可以吗(-ish),还是应该更改某些内容以使其按预期工作?
预先感谢您的答复。
TL; DR:MyPreferenceFragment实例创建成功,但是从未调用过@Override onCreate方法。
编辑1:好的,我确实找到了问题:当我在活动的onCreate方法中添加addPreferencesFromResource(prefs)作为调试测试时,我发现MyPreferenceFragment-class确实已初始化,然后完成了活动的onCreate方法(如果我不添加addPreferencesFromResource(prefs)测试行,该操作在findPreference()上将失败,并且只有在活动的onCreate方法完全完成后,它才会转到MyPreferenceFragment的onCreate方法。
有没有办法让PreferenceFrament的onCreate方法首先进入活动的onCreate方法的中间,因此在AddResourceApi11AndGreater()之后但在findPreference(LIST_PREFERENCE)之前呢?
将您的逻辑移至PF
,不要在PreferenceActivity
执行任何操作。 收听首选项更改的方式也有所变化。 检查代码。
public class MyPrefsActivity extends PreferenceActivity {
private static int prefs = R.xml.settings;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try{
getClass().getMethod("getFragmentManager");
AddResourceApi11AndGreater();
}
catch(NoSuchMethodException e){ // Android API < 11
AddResourceApiLessThan11();
}
}
@SuppressWarnings("deprecation")
protected void AddResourceApiLessThan11(){
addPreferencesFromResource(prefs);
}
@TargetApi(11)
protected void AddResourceApi11AndGreater(){
getFragmentManager().beginTransaction().replace(android.R.id.content,
new PF()).commit();
}
@TargetApi(11)
public static class PF extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
private ImageButton cbButton, spinnerButton, popupButton;
private final String LIST_PREFERENCE = "prefCheckboxOption";
@Override
public void onCreate(final Bundle savedInstanceState){
super.onCreate(savedInstanceState);
addPreferencesFromResource(MyPrefsActivity.prefs); // outer class
// private members seem to be visible for inner class, and
// making it static made things so much easier
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.registerOnSharedPreferenceChangeListener(this);
ListPreference listPreference = (ListPreference) findPreference(LIST_PREFERENCE);
if(listPreference.getValue() == null)
listPreference.setValue("0");
cbButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnCheckbox);
spinnerButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnSpinner);
popupButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnPopup);
setChosenPreference(Integer.valueOf(preferences.getString(LIST_PREFERENCE, "0")));
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
int chosen_option = Integer.valueOf(sharedPreferences.getString(key, "0"));
setChosenPreference(chosen_option);
}
private void setChosenPreference(int chosen_value){
// First put all Visibilities on GONE
cbButton.setVisibility(View.GONE);
spinnerButton.setVisibility(View.GONE);
popupButton.setVisibility(View.GONE);
// Then turn the chosen on VISIBLE again
switch(chosen_value){
case 0: // Multi-Click CheckBox
default:
cbButton.setVisibility(View.VISIBLE);
break;
case 1: // Dropdown CheckBox
spinnerButton.setVisibility(View.VISIBLE);
break;
case 2: // Pop-up CheckBox
popupButton.setVisibility(View.VISIBLE);
break;
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.