This commit is contained in:
serso 2011-09-21 00:33:29 +04:00
parent 62044e13f9
commit 56d6298c57
14 changed files with 404 additions and 170 deletions

View File

@ -6,7 +6,6 @@
</declare-styleable> </declare-styleable>
<declare-styleable name="NumberRangeSeekBar"> <declare-styleable name="NumberRangeSeekBar">
<attr name="min" format="string"/> <attr name="boundaries" format="string"/>
<attr name="max" format="string"/>
</declare-styleable> </declare-styleable>
</resources> </resources>

View File

@ -14,14 +14,26 @@
<org.solovyev.android.view.prefs.IntegerRangeSeekBarPreference <org.solovyev.android.view.prefs.IntegerRangeSeekBarPreference
a:key="touch.duration" a:key="org.solovyev.android.calculator.DragButtonCalibrationActivity_distance"
a:title="Duration of something" a:title="Distance of drag event"
a:summary="How long something will last" a:text=" pxs"
a:dialogMessage="Something duration" a:defaultValue="40;150"
a:defaultValue="5" range:boundaries="15;500"/>
a:text=" minutes"
range:min="10" <org.solovyev.android.view.prefs.IntegerRangeSeekBarPreference
range:max="600"/> a:key="org.solovyev.android.calculator.DragButtonCalibrationActivity_duration"
a:title="Duration of drag event"
a:text=" ms"
a:defaultValue="40;1000"
range:boundaries="5;4000"/>
<org.solovyev.android.view.prefs.IntegerRangeSeekBarPreference
a:key="org.solovyev.android.calculator.DragButtonCalibrationActivity_angle"
a:title="Angle of drag event"
a:text=" degrees"
a:defaultValue="130;180"
range:boundaries="100;180"/>
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>

View File

@ -11,6 +11,7 @@ import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -18,12 +19,10 @@ import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.view.widgets.*; import org.solovyev.android.view.widgets.*;
import org.solovyev.common.FloatIntervalMapper;
import org.solovyev.common.collections.ManyValuedHashMap; import org.solovyev.common.collections.ManyValuedHashMap;
import org.solovyev.common.collections.ManyValuedMap; import org.solovyev.common.collections.ManyValuedMap;
import org.solovyev.common.utils.Interval; import org.solovyev.common.utils.*;
import org.solovyev.common.utils.IntervalImpl;
import org.solovyev.common.utils.MathUtils;
import org.solovyev.common.utils.Point2d;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -42,13 +41,6 @@ public class DragButtonCalibrationActivity extends Activity {
private final Map<DragButton, CalibrationArrow> map = new HashMap<DragButton, CalibrationArrow>(); private final Map<DragButton, CalibrationArrow> map = new HashMap<DragButton, CalibrationArrow>();
public static final String PREFERENCES = "dragButtonPreferences";
public static final String PREFERENCES_FIRST_RUN = "firstRun";
public static final String PREFERENCES_MIN = "min";
public static final String PREFERENCES_MAX = "max";
private static final float DEFAULT_VALUE = -999; private static final float DEFAULT_VALUE = -999;
private static final int MIN_HISTORY_FOR_CALIBRATION = 10; private static final int MIN_HISTORY_FOR_CALIBRATION = 10;
public static final String INTENT_ACTION = "org.solovyev.android.calculator.DragButtonPreferencesChanged"; public static final String INTENT_ACTION = "org.solovyev.android.calculator.DragButtonPreferencesChanged";
@ -168,7 +160,7 @@ public class DragButtonCalibrationActivity extends Activity {
Log.d(this.getClass().getName(), "Time statistics: "); Log.d(this.getClass().getName(), "Time statistics: ");
logStatData(timeStatData); logStatData(timeStatData);
final SharedPreferences settings = getSharedPreferences(PREFERENCES, 0); final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
final SharedPreferences.Editor editor = settings.edit(); final SharedPreferences.Editor editor = settings.edit();
setPreferences(angleStatData, editor, PreferenceType.angle); setPreferences(angleStatData, editor, PreferenceType.angle);
@ -186,59 +178,61 @@ public class DragButtonCalibrationActivity extends Activity {
} }
private void setPreferences(@NotNull Map<DragDirection, MathUtils.StatData> statData, @NotNull SharedPreferences.Editor editor, @NotNull PreferenceType preferenceType) { private void setPreferences(@NotNull Map<DragDirection, MathUtils.StatData> statData, @NotNull SharedPreferences.Editor editor, @NotNull PreferenceType preferenceType) {
final Mapper<Interval<Float>> mapper = new FloatIntervalMapper();
for (Map.Entry<DragDirection, MathUtils.StatData> entry : statData.entrySet()) { for (Map.Entry<DragDirection, MathUtils.StatData> entry : statData.entrySet()) {
final float min = (float) entry.getValue().getMean() - 2 * (float) entry.getValue().getStandardDeviation(); final float min = (float) entry.getValue().getMean() - 2 * (float) entry.getValue().getStandardDeviation();
final float max = (float) entry.getValue().getMean() + 2 * (float) entry.getValue().getStandardDeviation(); final float max = (float) entry.getValue().getMean() + 2 * (float) entry.getValue().getStandardDeviation();
editor.putFloat(preferenceType.name() + "_" + entry.getKey().name() + "_" + PREFERENCES_MIN, Math.max(0, min)); editor.putString(getPreferenceId(preferenceType, entry.getKey()), mapper.formatValue(transformInterval(preferenceType, entry.getKey(), new IntervalImpl<Float>(Math.max(0, min), max))));
editor.putFloat(preferenceType.name() + "_" + entry.getKey().name() + "_" + PREFERENCES_MAX, max);
} }
} }
// todo serso: currently we do not use direction
public static String getPreferenceId(@NotNull PreferenceType preferenceType, @NotNull DragDirection direction) {
return "org.solovyev.android.calculator.DragButtonCalibrationActivity" + "_" + preferenceType.name() /*+ "_" + direction.name()*/;
}
@NotNull @NotNull
public static Preferences getPreferences(@NotNull Context context) { public static Preferences getPreferences(@NotNull Context context) {
SharedPreferences preferences = context.getSharedPreferences(PREFERENCES, MODE_PRIVATE); final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
final Mapper<Interval<Float>> mapper = new FloatIntervalMapper();
final Preferences result = new Preferences(); final Preferences result = new Preferences();
for (PreferenceType preferenceType : PreferenceType.values()) { for (PreferenceType preferenceType : PreferenceType.values()) {
for (DragDirection dragDirection : DragDirection.values()) { for (DragDirection dragDirection : DragDirection.values()) {
final float defaultMin; final Interval<Float> defaultValue;
final float defaultMax;
switch (preferenceType) { switch (preferenceType) {
case angle: case angle:
switch (dragDirection) { switch (dragDirection) {
case up: case up:
defaultMin = 130f; defaultValue = new IntervalImpl<Float>(130f, 180f);
defaultMax = 180f;
break; break;
case down: case down:
defaultMin = 0f; defaultValue = new IntervalImpl<Float>(0f, 50f);
defaultMax = 50f;
break; break;
default: default:
defaultMin = 0; defaultValue = new IntervalImpl<Float>(0f, 0f);
defaultMax = 0;
} }
break; break;
case distance: case distance:
defaultMin = 10f; defaultValue = new IntervalImpl<Float>(10f, 150f);
defaultMax = 150f;
break; break;
case duration: case duration:
defaultMin = 40f; defaultValue = new IntervalImpl<Float>(40f, 1000f);
defaultMax = 1000f;
break; break;
default: default:
defaultMin = DEFAULT_VALUE; defaultValue = new IntervalImpl<Float>(DEFAULT_VALUE, DEFAULT_VALUE);
defaultMax = DEFAULT_VALUE;
} }
final float min = preferences.getFloat(preferenceType.name() + "_" + dragDirection.name() + "_" + PREFERENCES_MIN, defaultMin); final String value = preferences.getString(getPreferenceId(preferenceType, dragDirection), mapper.formatValue(defaultValue));
final float max = preferences.getFloat(preferenceType.name() + "_" + dragDirection.name() + "_" + PREFERENCES_MAX, defaultMax);
if (min != DEFAULT_VALUE && max != DEFAULT_VALUE) { final Interval<Float> interval = mapper.parseValue(value);
final DragPreference directionPreference = new DragPreference(dragDirection, new IntervalImpl<Float>(min, max)); transformInterval(preferenceType, dragDirection, interval);
if (new IntervalImpl<Float>(DEFAULT_VALUE, DEFAULT_VALUE).equals(interval)) {
assert interval != null;
final DragPreference directionPreference = new DragPreference(dragDirection, interval);
Preference preference = result.getPreferencesMap().get(preferenceType); Preference preference = result.getPreferencesMap().get(preferenceType);
if (preference == null) { if (preference == null) {
@ -257,6 +251,17 @@ public class DragButtonCalibrationActivity extends Activity {
return result; return result;
} }
@NotNull
private static Interval<Float> transformInterval(@NotNull PreferenceType preferenceType, @NotNull DragDirection dragDirection, @NotNull Interval<Float> interval) {
if ( preferenceType == PreferenceType.angle && dragDirection == DragDirection.down ) {
final Interval<Float> clone = interval.clone();
interval.setLeftBorder(180f - clone.getRightBorder());
interval.setRightBorder(180f - clone.getLeftBorder());
}
return interval;
}
public static class DragPreference { public static class DragPreference {
@NotNull @NotNull

View File

@ -4,17 +4,19 @@ import android.content.Context;
import android.preference.DialogPreference; import android.preference.DialogPreference;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.Gravity; import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.common.utils.Mapper;
/** /**
* User: serso * User: serso
* Date: 9/19/11 * Date: 9/19/11
* Time: 3:17 PM * Time: 3:17 PM
*/ */
public class AbstractDialogPreference extends DialogPreference { public abstract class AbstractDialogPreference<T> extends DialogPreference {
@NotNull @NotNull
protected static final String androidns = "http://schemas.android.com/apk/res/android"; protected static final String androidns = "http://schemas.android.com/apk/res/android";
@ -26,38 +28,118 @@ public class AbstractDialogPreference extends DialogPreference {
protected final Context context; protected final Context context;
@Nullable @Nullable
protected String dialogMessage; protected String description;
public AbstractDialogPreference(Context context, AttributeSet attrs) { @Nullable
protected T value;
@Nullable
private T defaultValue;
@Nullable
protected String valueText;
@Nullable
private final String defaultStringValue;
public AbstractDialogPreference(Context context, AttributeSet attrs, @Nullable String defaultStringValue) {
super(context, attrs); super(context, attrs);
this.context = context; this.context = context;
this.defaultStringValue = defaultStringValue;
dialogMessage = attrs.getAttributeValue(androidns, "dialogMessage"); final String defaultValueFromAttrs = attrs.getAttributeValue(androidns, "defaultValue");
if ( defaultValueFromAttrs != null ) {
defaultValue = getMapper().parseValue(defaultValueFromAttrs);
} else if (defaultStringValue != null) {
defaultValue = getMapper().parseValue(defaultStringValue);
} else {
throw new IllegalArgumentException();
}
description = attrs.getAttributeValue(androidns, "dialogMessage");
valueText = attrs.getAttributeValue(androidns, "text");
} }
@Override @Override
@NotNull
protected LinearLayout onCreateDialogView() { protected LinearLayout onCreateDialogView() {
LinearLayout.LayoutParams params; if (shouldPersist()) {
LinearLayout layout = new LinearLayout(context); value = getPersistedValue();
layout.setOrientation(LinearLayout.VERTICAL); }
layout.setPadding(6, 6, 6, 6);
final LinearLayout result = new LinearLayout(context);
final TextView splashText = new TextView(context); result.setOrientation(LinearLayout.VERTICAL);
if (dialogMessage != null) { result.setPadding(6, 6, 6, 6);
splashText.setText(dialogMessage);
if (description != null) {
final TextView splashText = new TextView(context);
splashText.setText(description);
result.addView(splashText);
} }
layout.addView(splashText);
valueTextView = new TextView(context); valueTextView = new TextView(context);
valueTextView.setGravity(Gravity.CENTER_HORIZONTAL); valueTextView.setGravity(Gravity.CENTER_HORIZONTAL);
valueTextView.setTextSize(32); valueTextView.setTextSize(32);
params = new LinearLayout.LayoutParams(
final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT); LinearLayout.LayoutParams.WRAP_CONTENT);
layout.addView(valueTextView, params); result.addView(valueTextView, params);
return layout; return result;
} }
@Override
protected void onSetInitialValue(boolean restore, Object defaultValue) {
super.onSetInitialValue(restore, defaultValue);
if (restore) {
if (shouldPersist()) {
value = getPersistedValue();
} else {
value = this.defaultValue;
}
} else {
value = (T) defaultValue;
if (shouldPersist()) {
persist(this.value);
}
}
}
@Override
protected void onBindDialogView(View v) {
super.onBindDialogView(v);
initPreferenceView();
}
protected abstract void initPreferenceView();
private T getPersistedValue() {
String persistedString = getPersistedString(defaultStringValue);
if ( persistedString == defaultStringValue ) {
return defaultValue;
} else {
return getMapper().parseValue(persistedString);
}
}
protected void persistValue(@Nullable T value) {
if (callChangeListener(value)) {
if (shouldPersist()) {
persist(value);
}
}
}
private void persist(@Nullable T value) {
final String toBePersistedString = getMapper().formatValue(value);
if (toBePersistedString != null) {
persistString(toBePersistedString);
}
}
@NotNull
protected abstract Mapper<T> getMapper();
} }

View File

@ -9,7 +9,8 @@ package org.solovyev.android.view.prefs;
import android.content.Context; import android.content.Context;
import android.util.AttributeSet; import android.util.AttributeSet;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.solovyev.common.utils.Converter; import org.solovyev.common.IntegerIntervalMapper;
import org.solovyev.common.utils.*;
/** /**
* User: serso * User: serso
@ -24,13 +25,8 @@ public class IntegerRangeSeekBarPreference extends RangeSeekBarPreference<Intege
@NotNull @NotNull
@Override @Override
Converter<String, Integer> getConverter() { protected Mapper<Interval<Integer>> getMapper() {
return new Converter<String, Integer>() { return new IntegerIntervalMapper();
@NotNull
@Override
public Integer convert(@NotNull String value) {
return Integer.valueOf(value);
}
};
} }
} }

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.view.prefs;
import org.jetbrains.annotations.Nullable;
/**
* User: serso
* Date: 9/20/11
* Time: 10:15 PM
*/
public interface PersistenceValueGetter<T> {
@Nullable
T getPersistedValue(@Nullable T defaultValue);
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.view.prefs;
import org.jetbrains.annotations.Nullable;
/**
* User: serso
* Date: 9/20/11
* Time: 10:14 PM
*/
public interface PersistenceValueSetter<T> {
void persist(@Nullable T value);
}

View File

@ -2,24 +2,19 @@ package org.solovyev.android.view.prefs;
import android.content.Context; import android.content.Context;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.view.widgets.AbstractRangeSeekBar; import org.solovyev.android.view.widgets.AbstractRangeSeekBar;
import org.solovyev.android.view.widgets.NumberRangeSeekBar; import org.solovyev.android.view.widgets.NumberRangeSeekBar;
import org.solovyev.common.utils.CollectionsUtils; import org.solovyev.common.utils.Interval;
import org.solovyev.common.utils.Converter; import org.solovyev.common.utils.NumberInterval;
import org.solovyev.common.utils.StringMapper;
import java.util.Arrays;
import java.util.List;
/** /**
* User: serso * User: serso
* Date: 9/19/11 * Date: 9/19/11
* Time: 12:27 PM * Time: 12:27 PM
*/ */
public abstract class RangeSeekBarPreference<T extends Number> extends AbstractDialogPreference implements AbstractRangeSeekBar.OnRangeSeekBarChangeListener<T> { public abstract class RangeSeekBarPreference<T extends Number> extends AbstractDialogPreference<Interval<T>> implements AbstractRangeSeekBar.OnRangeSeekBarChangeListener<T> {
public final static String localNameSpace = "http://schemas.android.com/apk/res/org.solovyev.android.calculator"; public final static String localNameSpace = "http://schemas.android.com/apk/res/org.solovyev.android.calculator";
@ -27,52 +22,26 @@ public abstract class RangeSeekBarPreference<T extends Number> extends AbstractD
private AbstractRangeSeekBar<T> rangeSeekBar; private AbstractRangeSeekBar<T> rangeSeekBar;
@NotNull @NotNull
private T min; private final Interval<T> boundaries;
@NotNull
private T max;
@NotNull
private T selectedMin;
@NotNull
private T selectedMax;
public RangeSeekBarPreference(@NotNull Context context, AttributeSet attrs) { public RangeSeekBarPreference(@NotNull Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs, null);
boundaries = getMapper().parseValue(attrs.getAttributeValue(localNameSpace, "boundaries"));
final Converter<String, T> c = getConverter(); assert boundaries != null;
this.rangeSeekBar = new NumberRangeSeekBar<T>(boundaries, null, context);
String minString = attrs.getAttributeValue(localNameSpace, "min");
min = c.convert(minString == null ? "0" : minString);
String maxString = attrs.getAttributeValue(localNameSpace, "max");
max = c.convert(maxString == null ? "100" : maxString);
this.rangeSeekBar = new NumberRangeSeekBar<T>(min, max, null, context);
rangeSeekBar.setOnRangeSeekBarChangeListener(this); rangeSeekBar.setOnRangeSeekBarChangeListener(this);
} }
public void setMin(@NotNull String min) {
this.min = getConverter().convert(min);
}
public void setMax(@NotNull String max) {
this.max = getConverter().convert(max);
}
@NotNull @NotNull
abstract Converter<String, T> getConverter();
@Override @Override
protected LinearLayout onCreateDialogView() { protected LinearLayout onCreateDialogView() {
final LinearLayout result = super.onCreateDialogView(); final LinearLayout result = super.onCreateDialogView();
this.rangeSeekBar = new NumberRangeSeekBar<T>(min, max, null, context); this.rangeSeekBar = new NumberRangeSeekBar<T>(boundaries, null, context);
rangeSeekBar.setOnRangeSeekBarChangeListener(this); rangeSeekBar.setOnRangeSeekBarChangeListener(this);
initRangeSeekBar(); initPreferenceView();
result.addView(rangeSeekBar); result.addView(rangeSeekBar);
@ -80,38 +49,24 @@ public abstract class RangeSeekBarPreference<T extends Number> extends AbstractD
} }
@Override @Override
protected void onBindDialogView(View v) { protected void initPreferenceView() {
super.onBindDialogView(v); if (value != null) {
initRangeSeekBar(); rangeSeekBar.setSelectedMinValue(value.getLeftBorder());
rangeSeekBar.setSelectedMaxValue(value.getRightBorder());
setValueText(value);
} }
private void initRangeSeekBar() {
rangeSeekBar.setSelectedMinValue(selectedMin);
rangeSeekBar.setSelectedMaxValue(selectedMax);
} }
@Override
protected void onSetInitialValue(boolean restore, Object defaultValue) {
super.onSetInitialValue(restore, defaultValue);
final List<String> values;
if (restore) {
values = CollectionsUtils.split(getPersistedString("0;100"), ";", new StringMapper());
} else {
values = CollectionsUtils.split(String.valueOf(defaultValue), ";", new StringMapper());
}
selectedMin = getConverter().convert(values.get(0));
selectedMax = getConverter().convert(values.get(1));
}
@Override @Override
public void rangeSeekBarValuesChanged(T minValue, T maxValue) { public void rangeSeekBarValuesChanged(T minValue, T maxValue) {
final String value = CollectionsUtils.formatValue(Arrays.asList(String.valueOf(minValue), String.valueOf(maxValue)), ";", new StringMapper()); final Interval<T> interval = new NumberInterval<T>(minValue, maxValue);
if (shouldPersist()) { persistValue(interval);
persistString(value);
setValueText(interval);
} }
callChangeListener(value);
private void setValueText(@NotNull Interval<T> interval) {
final String t = String.valueOf(interval);
valueTextView.setText(valueText == null ? t : t.concat(valueText));
} }
} }

View File

@ -8,11 +8,11 @@ package org.solovyev.android.view.prefs;
import android.content.Context; import android.content.Context;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View;
import android.widget.SeekBar;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.SeekBar;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.common.utils.Mapper;
/* The following code was written by Matthew Wiggins /* The following code was written by Matthew Wiggins
@ -21,24 +21,20 @@ import org.jetbrains.annotations.Nullable;
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
public class SeekBarPreference extends AbstractDialogPreference implements SeekBar.OnSeekBarChangeListener { public class SeekBarPreference extends AbstractDialogPreference<Integer> implements SeekBar.OnSeekBarChangeListener {
@NotNull @NotNull
private SeekBar seekBar; private SeekBar seekBar;
private int defaultValue, max, value = 0; private int max = 0;
@Nullable
protected String valueText;
public SeekBarPreference(Context context, AttributeSet attrs) { public SeekBarPreference(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs, "50");
defaultValue = attrs.getAttributeIntValue(androidns, "defaultValue", 0);
max = attrs.getAttributeIntValue(androidns, "max", 100); max = attrs.getAttributeIntValue(androidns, "max", 100);
valueText = attrs.getAttributeValue(androidns, "text");
} }
@NotNull
@Override @Override
protected LinearLayout onCreateDialogView() { protected LinearLayout onCreateDialogView() {
final LinearLayout layout = super.onCreateDialogView(); final LinearLayout layout = super.onCreateDialogView();
@ -47,40 +43,45 @@ public class SeekBarPreference extends AbstractDialogPreference implements SeekB
seekBar.setOnSeekBarChangeListener(this); seekBar.setOnSeekBarChangeListener(this);
layout.addView(seekBar, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); layout.addView(seekBar, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
if (shouldPersist()) initPreferenceView();
value = getPersistedInt(defaultValue);
initSeekBar();
return layout; return layout;
} }
private void initSeekBar() { @Override
protected void initPreferenceView() {
seekBar.setMax(max); seekBar.setMax(max);
if (value != null) {
seekBar.setProgress(value); seekBar.setProgress(value);
setValueText(value);
}
}
@NotNull
@Override
protected Mapper<Integer> getMapper() {
return new Mapper<Integer>() {
@Override
public String formatValue(@Nullable Integer integer) throws IllegalArgumentException {
return integer == null ? null : String.valueOf(integer);
} }
@Override @Override
protected void onBindDialogView(View v) { public Integer parseValue(@Nullable String s) throws IllegalArgumentException {
super.onBindDialogView(v); return s == null ? null : Integer.valueOf(s);
initSeekBar();
} }
};
@Override
protected void onSetInitialValue(boolean restore, Object defaultValue) {
super.onSetInitialValue(restore, defaultValue);
if (restore)
value = shouldPersist() ? getPersistedInt(this.defaultValue) : 0;
else
value = (Integer) defaultValue;
} }
public void onProgressChanged(SeekBar seek, int value, boolean fromTouch) { public void onProgressChanged(SeekBar seek, int value, boolean fromTouch) {
setValueText(value);
persistValue(value);
}
private void setValueText(int value) {
String t = String.valueOf(value); String t = String.valueOf(value);
valueTextView.setText(valueText == null ? t : t.concat(valueText)); valueTextView.setText(valueText == null ? t : t.concat(valueText));
if (shouldPersist())
persistInt(value);
callChangeListener(new Integer(value));
} }
public void onStartTrackingTouch(SeekBar seek) { public void onStartTrackingTouch(SeekBar seek) {
@ -99,7 +100,6 @@ public class SeekBarPreference extends AbstractDialogPreference implements SeekB
public void setProgress(int progress) { public void setProgress(int progress) {
value = progress; value = progress;
if (seekBar != null)
seekBar.setProgress(progress); seekBar.setProgress(progress);
} }

View File

@ -4,6 +4,7 @@ import android.content.Context;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.common.utils.Converter; import org.solovyev.common.utils.Converter;
import org.solovyev.common.utils.Interval;
import org.solovyev.common.utils.NumberValuer; import org.solovyev.common.utils.NumberValuer;
/** /**
@ -16,6 +17,11 @@ public class NumberRangeSeekBar<T extends Number> extends AbstractRangeSeekBar<T
@NotNull @NotNull
private final NumberType numberType; private final NumberType numberType;
public NumberRangeSeekBar(@NotNull Interval<T> boundaries, @Nullable Integer steps, Context context) throws IllegalArgumentException {
this(boundaries.getLeftBorder(), boundaries.getRightBorder(), steps, context);
}
/** /**
* Creates a new RangeSeekBar. * Creates a new RangeSeekBar.
* *

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.common;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.common.utils.*;
import java.util.Arrays;
import java.util.List;
/**
* User: serso
* Date: 9/21/11
* Time: 12:02 AM
*/
public abstract class AbstractIntervalMapper<T> implements Mapper<Interval<T>> {
@Override
public String formatValue(@Nullable Interval<T> interval) throws IllegalArgumentException {
if (interval != null) {
return CollectionsUtils.formatValue(Arrays.asList(interval.getLeftBorder(), interval.getRightBorder()), ";", getFormatter());
} else {
return null;
}
}
@NotNull
protected abstract Formatter<T> getFormatter();
@Override
public Interval<T> parseValue(@Nullable String s) throws IllegalArgumentException {
final List<T> list = CollectionsUtils.split(s, ";", getParser());
assert list.size() == 2;
return new IntervalImpl<T>(list.get(0), list.get(1));
}
@NotNull
protected abstract Parser<T> getParser();
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.common;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.common.math.ValueOfFormatter;
import org.solovyev.common.utils.Formatter;
import org.solovyev.common.utils.Parser;
/**
* User: serso
* Date: 9/21/11
* Time: 12:06 AM
*/
public class FloatIntervalMapper extends AbstractIntervalMapper<Float> {
@NotNull
@Override
protected Formatter<Float> getFormatter() {
return new ValueOfFormatter<Float>();
}
@NotNull
@Override
protected Parser<Float> getParser() {
return new Parser<Float>() {
@Override
public Float parseValue(@Nullable String s) throws IllegalArgumentException {
return Float.valueOf(s);
}
};
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.common;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.common.math.ValueOfFormatter;
import org.solovyev.common.utils.*;
/**
* User: serso
* Date: 9/20/11
* Time: 11:56 PM
*/
public class IntegerIntervalMapper extends AbstractIntervalMapper<Integer> {
@NotNull
protected Formatter<Integer> getFormatter() {
return new ValueOfFormatter<Integer>();
}
@NotNull
protected Parser<Integer> getParser() {
return new Parser<Integer>() {
@Override
public Integer parseValue(@Nullable String s) throws IllegalArgumentException {
return Integer.valueOf(s);
}
};
}
}

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.common.math;
import org.jetbrains.annotations.Nullable;
import org.solovyev.common.utils.Formatter;
/**
* User: serso
* Date: 9/20/11
* Time: 10:52 PM
*/
public class ValueOfFormatter<T> implements Formatter<T>{
@Override
public String formatValue(@Nullable T t) throws IllegalArgumentException {
return String.valueOf(t);
}
}