I have prepared a simple test project for my question at GitHub.
In my project there is a custom inline SeekBarPreference, which mostly works fine (its summary is updated when seekbar is being dragged and it saves integer value):
However there is a problem:
On the very 1st run of the app (you might need to uninstall my app when you try see the error again) the progress of the SeekBar
is not set (but the summaries are set):
My question is: how to fix this issue in my code?
I have tried adding mSeekBar.setProgress(mProgress) in different spots of SeekBarPreference.java, but just can't find the correct place for that code.
Below are excerpts from my source code (in case Stackoverflow ever outlives GitHub) -
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
getFragmentManager().beginTransaction()
.addToBackStack(null)
.replace(R.id.root, new PrefFragment(), "prefs")
.commit();
@Override
public void onResume() {
super.onResume();
SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
// set the summaries from saved values
onSharedPreferenceChanged(prefs, SEEK_1);
onSharedPreferenceChanged(prefs, SEEK_2);
prefs.registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (SEEK_1.equals(key)) {
int i1 = prefs.getInt(key, DEFAULT_1);
mSeek1.setSummary("$ " + i1);
} else if (SEEK_2.equals(key)) {
int i2 = prefs.getInt(key, DEFAULT_2);
mSeek2.setSummary("$ " + i2);
}
}
SeekBarPreference.java (the complete source code):
public class SeekBarPreference extends Preference implements OnSeekBarChangeListener {
private SeekBar mSeekBar; // FIXME how to set its progress?
private int mProgress;
public SeekBarPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected View onCreateView(ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.preference_seekbar, parent, false);
// can also be done in onBindView, does not work either
mSeekBar = (SeekBar) view.findViewById(R.id.seekbar);
mSeekBar.setProgress(mProgress);
mSeekBar.setOnSeekBarChangeListener(this);
return view;
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (!fromUser)
return;
setValue(progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// not used
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// not used
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
setValue(restoreValue ? getPersistedInt(mProgress) : (Integer) defaultValue);
}
public void setValue(int value) {
if (shouldPersist()) {
persistInt(value);
}
if (value != mProgress) {
mProgress = value;
notifyChanged();
}
}
}
UPDATE:
What I have unsuccessfully tried sofar -
1) Adding the following lines to the onCreateView()
method:
int progress = getPersistedInt(mProgress); // shows 0 in debugger
mSeekBar.setProgress(progress);
2) Adding the following lines to the setValue()
method:
if (value != mProgress) {
mProgress = value;
mSeekBar.setProgress(mProgress);
notifyChanged();
}
Alas this does not work, the progress of the mSeekBar
stays at 0.
Also, there is a SeekBarPreference by Google - but I don't understand how it works there (or if it works at all).
mSeek1.setSummary("$ " + i1);
but you never set the progress of the bar itself in this code block. – FlanneletteonSharedPreferenceChanged(prefs, SEEK_1)
in PrefFragment.java – DevlinonSharedPreferenceChanged(prefs, SEEK_1)
, what I see happening is: ensuring your string keys match, then getting the int value using the appropriate key, then setting the summary for the seek bar using the int value returned or the default value. So unless setting the summary also sets the current progress of the progress bar, I'm not seeing it being set in that code block. – FlanneletteTextEditPreference
, not forCheckBoxPreference
, not for my customSeekBarPreference
. And still for the first 2 kinds of preferences everything works. And for my custom preference it almost works (the summary is ok). So the code of the SeekBarPreference.java should be fixed (and not of the PrefFragment.java). – DevlinSeekBarPreference
you're saying that you're not getting a value (and thus getting the default value for an int) when you callgetPersistedInt
fromonCreateView
but you are getting a value when you callgetPersistedInt
fromonSetInitialValue
, is that correct? – Flannelette