Ok, I know there have been a lot of questions about SharedPreferences in Android asked before, and I did manage to get quite far, but since I'm kinda new to SharedPreferences I don't know the last few steps to get it to work.
In my MainActivity I have the following:
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;
}
}
And this is 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
}
}
}
And the 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>
and 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>
(Of course I've also included the MyPrefsActivity in the AndroidManifest.xml)
My goal is to make one of the three checkbox-option (found in the setChosenPreference method) VISIBLE, and the other two GONE, based on the preference selected in the ListPreference.
Right now the Listpreference in both the onCreate() method and onSharedPreferenceChanged() is null and giving a NullPointerException. So I set some breakpoints (see the three " * ") and the reason they are null is because the third " * " (in the static class PF) isn't called.
The addPreferencesFromResources should be called before using findPreference, otherwise it will return null. Does anyone know why during debugging I do get to the second " * " in the AddResourceApi11AndGreater() method, but I'm not getting to the third one in the MyPreferenceFragment-class onCreate method() ?.. the onCreate isn't called at all..
Also, does the rest of my code seems ok(-ish) or should I change something in order to make it work as I intended?
Thanks in advance for the responses.
TL;DR: MyPreferenceFragment instantion is created successfully, but it's @Override onCreate method is never called.
EDIT 1: Ok, I did found the problem: When I added addPreferencesFromResource(prefs) in the activity's onCreate method as a debug-test, I found out that the MyPreferenceFragment-class is indeed being initialized, then it finishes the activity's onCreate method (which would have failed at findPreference() if I didn't added the addPreferencesFromResource(prefs) test-line), and only after the activity's onCreate method is completely finished, it goes to the MyPreferenceFragment's onCreate method.
Is there a way to let the PreferenceFrament's onCreate method go first, while in the middle of the activity's onCreate method, so after AddResourceApi11AndGreater() but before findPreference(LIST_PREFERENCE)?
Move your logic to PF
, don't do things in PreferenceActivity
.
There are also changes in the way of listening to the preferences changes. Check the code.
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;
}
}
}
}