prefs
This commit is contained in:
@@ -4,17 +4,19 @@ import android.content.Context;
|
||||
import android.preference.DialogPreference;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.common.utils.Mapper;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/19/11
|
||||
* Time: 3:17 PM
|
||||
*/
|
||||
public class AbstractDialogPreference extends DialogPreference {
|
||||
public abstract class AbstractDialogPreference<T> extends DialogPreference {
|
||||
|
||||
@NotNull
|
||||
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;
|
||||
|
||||
@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);
|
||||
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
|
||||
@NotNull
|
||||
protected LinearLayout onCreateDialogView() {
|
||||
LinearLayout.LayoutParams params;
|
||||
LinearLayout layout = new LinearLayout(context);
|
||||
layout.setOrientation(LinearLayout.VERTICAL);
|
||||
layout.setPadding(6, 6, 6, 6);
|
||||
|
||||
final TextView splashText = new TextView(context);
|
||||
if (dialogMessage != null) {
|
||||
splashText.setText(dialogMessage);
|
||||
if (shouldPersist()) {
|
||||
value = getPersistedValue();
|
||||
}
|
||||
|
||||
final LinearLayout result = new LinearLayout(context);
|
||||
result.setOrientation(LinearLayout.VERTICAL);
|
||||
result.setPadding(6, 6, 6, 6);
|
||||
|
||||
if (description != null) {
|
||||
final TextView splashText = new TextView(context);
|
||||
splashText.setText(description);
|
||||
result.addView(splashText);
|
||||
}
|
||||
layout.addView(splashText);
|
||||
|
||||
valueTextView = new TextView(context);
|
||||
valueTextView.setGravity(Gravity.CENTER_HORIZONTAL);
|
||||
valueTextView.setTextSize(32);
|
||||
params = new LinearLayout.LayoutParams(
|
||||
|
||||
final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.FILL_PARENT,
|
||||
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();
|
||||
}
|
||||
|
@@ -9,7 +9,8 @@ package org.solovyev.android.view.prefs;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.common.utils.Converter;
|
||||
import org.solovyev.common.IntegerIntervalMapper;
|
||||
import org.solovyev.common.utils.*;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
@@ -24,13 +25,8 @@ public class IntegerRangeSeekBarPreference extends RangeSeekBarPreference<Intege
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
Converter<String, Integer> getConverter() {
|
||||
return new Converter<String, Integer>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Integer convert(@NotNull String value) {
|
||||
return Integer.valueOf(value);
|
||||
}
|
||||
};
|
||||
protected Mapper<Interval<Integer>> getMapper() {
|
||||
return new IntegerIntervalMapper();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -2,24 +2,19 @@ package org.solovyev.android.view.prefs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.view.widgets.AbstractRangeSeekBar;
|
||||
import org.solovyev.android.view.widgets.NumberRangeSeekBar;
|
||||
import org.solovyev.common.utils.CollectionsUtils;
|
||||
import org.solovyev.common.utils.Converter;
|
||||
import org.solovyev.common.utils.StringMapper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.solovyev.common.utils.Interval;
|
||||
import org.solovyev.common.utils.NumberInterval;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/19/11
|
||||
* 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";
|
||||
|
||||
@@ -27,52 +22,26 @@ public abstract class RangeSeekBarPreference<T extends Number> extends AbstractD
|
||||
private AbstractRangeSeekBar<T> rangeSeekBar;
|
||||
|
||||
@NotNull
|
||||
private T min;
|
||||
|
||||
@NotNull
|
||||
private T max;
|
||||
|
||||
@NotNull
|
||||
private T selectedMin;
|
||||
|
||||
@NotNull
|
||||
private T selectedMax;
|
||||
|
||||
private final Interval<T> boundaries;
|
||||
|
||||
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();
|
||||
|
||||
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);
|
||||
assert boundaries != null;
|
||||
this.rangeSeekBar = new NumberRangeSeekBar<T>(boundaries, null, context);
|
||||
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
|
||||
abstract Converter<String, T> getConverter();
|
||||
|
||||
@Override
|
||||
protected LinearLayout 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);
|
||||
initRangeSeekBar();
|
||||
initPreferenceView();
|
||||
|
||||
result.addView(rangeSeekBar);
|
||||
|
||||
@@ -80,38 +49,24 @@ public abstract class RangeSeekBarPreference<T extends Number> extends AbstractD
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindDialogView(View v) {
|
||||
super.onBindDialogView(v);
|
||||
initRangeSeekBar();
|
||||
}
|
||||
|
||||
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());
|
||||
protected void initPreferenceView() {
|
||||
if (value != null) {
|
||||
rangeSeekBar.setSelectedMinValue(value.getLeftBorder());
|
||||
rangeSeekBar.setSelectedMaxValue(value.getRightBorder());
|
||||
setValueText(value);
|
||||
}
|
||||
|
||||
selectedMin = getConverter().convert(values.get(0));
|
||||
selectedMax = getConverter().convert(values.get(1));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void rangeSeekBarValuesChanged(T minValue, T maxValue) {
|
||||
final String value = CollectionsUtils.formatValue(Arrays.asList(String.valueOf(minValue), String.valueOf(maxValue)), ";", new StringMapper());
|
||||
if (shouldPersist()) {
|
||||
persistString(value);
|
||||
}
|
||||
callChangeListener(value);
|
||||
final Interval<T> interval = new NumberInterval<T>(minValue, maxValue);
|
||||
persistValue(interval);
|
||||
|
||||
setValueText(interval);
|
||||
}
|
||||
|
||||
private void setValueText(@NotNull Interval<T> interval) {
|
||||
final String t = String.valueOf(interval);
|
||||
valueTextView.setText(valueText == null ? t : t.concat(valueText));
|
||||
}
|
||||
}
|
||||
|
@@ -8,11 +8,11 @@ package org.solovyev.android.view.prefs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.SeekBar;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.common.utils.Mapper;
|
||||
|
||||
|
||||
/* 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
|
||||
*/
|
||||
|
||||
public class SeekBarPreference extends AbstractDialogPreference implements SeekBar.OnSeekBarChangeListener {
|
||||
public class SeekBarPreference extends AbstractDialogPreference<Integer> implements SeekBar.OnSeekBarChangeListener {
|
||||
|
||||
@NotNull
|
||||
private SeekBar seekBar;
|
||||
|
||||
private int defaultValue, max, value = 0;
|
||||
|
||||
@Nullable
|
||||
protected String valueText;
|
||||
private int max = 0;
|
||||
|
||||
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);
|
||||
valueText = attrs.getAttributeValue(androidns, "text");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected LinearLayout onCreateDialogView() {
|
||||
final LinearLayout layout = super.onCreateDialogView();
|
||||
@@ -47,40 +43,45 @@ public class SeekBarPreference extends AbstractDialogPreference implements SeekB
|
||||
seekBar.setOnSeekBarChangeListener(this);
|
||||
layout.addView(seekBar, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
if (shouldPersist())
|
||||
value = getPersistedInt(defaultValue);
|
||||
|
||||
initSeekBar();
|
||||
initPreferenceView();
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
private void initSeekBar() {
|
||||
@Override
|
||||
protected void initPreferenceView() {
|
||||
seekBar.setMax(max);
|
||||
seekBar.setProgress(value);
|
||||
if (value != null) {
|
||||
seekBar.setProgress(value);
|
||||
setValueText(value);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected void onBindDialogView(View v) {
|
||||
super.onBindDialogView(v);
|
||||
initSeekBar();
|
||||
}
|
||||
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
|
||||
protected void onSetInitialValue(boolean restore, Object defaultValue) {
|
||||
super.onSetInitialValue(restore, defaultValue);
|
||||
if (restore)
|
||||
value = shouldPersist() ? getPersistedInt(this.defaultValue) : 0;
|
||||
else
|
||||
value = (Integer) defaultValue;
|
||||
@Override
|
||||
public Integer parseValue(@Nullable String s) throws IllegalArgumentException {
|
||||
return s == null ? null : Integer.valueOf(s);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void onProgressChanged(SeekBar seek, int value, boolean fromTouch) {
|
||||
setValueText(value);
|
||||
|
||||
persistValue(value);
|
||||
}
|
||||
|
||||
private void setValueText(int value) {
|
||||
String t = String.valueOf(value);
|
||||
valueTextView.setText(valueText == null ? t : t.concat(valueText));
|
||||
if (shouldPersist())
|
||||
persistInt(value);
|
||||
callChangeListener(new Integer(value));
|
||||
}
|
||||
|
||||
public void onStartTrackingTouch(SeekBar seek) {
|
||||
@@ -99,8 +100,7 @@ public class SeekBarPreference extends AbstractDialogPreference implements SeekB
|
||||
|
||||
public void setProgress(int progress) {
|
||||
value = progress;
|
||||
if (seekBar != null)
|
||||
seekBar.setProgress(progress);
|
||||
seekBar.setProgress(progress);
|
||||
}
|
||||
|
||||
public int getProgress() {
|
||||
|
@@ -4,6 +4,7 @@ import android.content.Context;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.common.utils.Converter;
|
||||
import org.solovyev.common.utils.Interval;
|
||||
import org.solovyev.common.utils.NumberValuer;
|
||||
|
||||
/**
|
||||
@@ -16,12 +17,17 @@ public class NumberRangeSeekBar<T extends Number> extends AbstractRangeSeekBar<T
|
||||
@NotNull
|
||||
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.
|
||||
*
|
||||
* @param minValue The minimum value of the selectable range.
|
||||
* @param maxValue The maximum value of the selectable range.
|
||||
* @param steps number of steps of range
|
||||
* @param steps number of steps of range
|
||||
* @param context parent context
|
||||
* @throws IllegalArgumentException Will be thrown if min/max value types are not one of Long, Double, Integer, Float, Short, Byte or BigDecimal.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user