forked from extern/Unexpected-Keyboard
ListGroupPreference: Make items abstract
Allow items to be of any class instead of strings. Item serialization and deserialization methods are in a separate class because they are also used in a static context.
This commit is contained in:
parent
20ab3915e8
commit
0269cd65ea
@ -17,10 +17,12 @@ import org.json.JSONException;
|
|||||||
|
|
||||||
/** Allows to enter custom keys to be added to the keyboard. This shows up at
|
/** Allows to enter custom keys to be added to the keyboard. This shows up at
|
||||||
the top of the "Add keys to the keyboard" option. */
|
the top of the "Add keys to the keyboard" option. */
|
||||||
public class CustomExtraKeysPreference extends ListGroupPreference
|
public class CustomExtraKeysPreference extends ListGroupPreference<String>
|
||||||
{
|
{
|
||||||
/** This pref stores a list of strings encoded as JSON. */
|
/** This pref stores a list of strings encoded as JSON. */
|
||||||
static final String KEY = "custom_extra_keys";
|
static final String KEY = "custom_extra_keys";
|
||||||
|
static final ListGroupPreference.Serializer<String> SERIALIZER =
|
||||||
|
new ListGroupPreference.StringSerializer();
|
||||||
|
|
||||||
public CustomExtraKeysPreference(Context context, AttributeSet attrs)
|
public CustomExtraKeysPreference(Context context, AttributeSet attrs)
|
||||||
{
|
{
|
||||||
@ -31,7 +33,7 @@ public class CustomExtraKeysPreference extends ListGroupPreference
|
|||||||
public static List<KeyValue> get(SharedPreferences prefs)
|
public static List<KeyValue> get(SharedPreferences prefs)
|
||||||
{
|
{
|
||||||
List<KeyValue> kvs = new ArrayList<KeyValue>();
|
List<KeyValue> kvs = new ArrayList<KeyValue>();
|
||||||
List<String> key_names = load_from_preferences(KEY, prefs, null);
|
List<String> key_names = load_from_preferences(KEY, prefs, null, SERIALIZER);
|
||||||
if (key_names != null)
|
if (key_names != null)
|
||||||
{
|
{
|
||||||
for (String key_name : key_names)
|
for (String key_name : key_names)
|
||||||
@ -40,8 +42,10 @@ public class CustomExtraKeysPreference extends ListGroupPreference
|
|||||||
return kvs;
|
return kvs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String label_of_value(String value, int i) { return value; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void select(final SelectionCallback callback)
|
void select(final SelectionCallback<String> callback)
|
||||||
{
|
{
|
||||||
new AlertDialog.Builder(getContext())
|
new AlertDialog.Builder(getContext())
|
||||||
.setView(R.layout.custom_extra_key_add_dialog)
|
.setView(R.layout.custom_extra_key_add_dialog)
|
||||||
@ -58,4 +62,7 @@ public class CustomExtraKeysPreference extends ListGroupPreference
|
|||||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Serializer<String> get_serializer() { return SERIALIZER; }
|
||||||
}
|
}
|
||||||
|
@ -13,10 +13,12 @@ import java.util.Arrays;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class LayoutsPreference extends ListGroupPreference
|
public class LayoutsPreference extends ListGroupPreference<String>
|
||||||
{
|
{
|
||||||
static final String KEY = "layouts";
|
static final String KEY = "layouts";
|
||||||
static final List<String> DEFAULT = Collections.singletonList("system");
|
static final List<String> DEFAULT = Collections.singletonList("system");
|
||||||
|
static final ListGroupPreference.Serializer<String> SERIALIZER =
|
||||||
|
new ListGroupPreference.StringSerializer();
|
||||||
|
|
||||||
/** Layout names as stored in the preferences. */
|
/** Layout names as stored in the preferences. */
|
||||||
List<String> _layout_names;
|
List<String> _layout_names;
|
||||||
@ -34,7 +36,7 @@ public class LayoutsPreference extends ListGroupPreference
|
|||||||
|
|
||||||
public static List<String> load_from_preferences(SharedPreferences prefs)
|
public static List<String> load_from_preferences(SharedPreferences prefs)
|
||||||
{
|
{
|
||||||
return load_from_preferences(KEY, prefs, DEFAULT);
|
return load_from_preferences(KEY, prefs, DEFAULT, SERIALIZER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -67,6 +69,9 @@ public class LayoutsPreference extends ListGroupPreference
|
|||||||
return (_values.size() > 1);
|
return (_values.size() > 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Serializer<String> get_serializer() { return SERIALIZER; }
|
||||||
|
|
||||||
void select(final SelectionCallback callback)
|
void select(final SelectionCallback callback)
|
||||||
{
|
{
|
||||||
ArrayAdapter layouts = new ArrayAdapter(getContext(), android.R.layout.simple_list_item_1, _layout_display_names);
|
ArrayAdapter layouts = new ArrayAdapter(getContext(), android.R.layout.simple_list_item_1, _layout_display_names);
|
||||||
|
@ -15,10 +15,10 @@ import org.json.JSONException;
|
|||||||
/** A list of preferences where the users can add items to the end and modify
|
/** A list of preferences where the users can add items to the end and modify
|
||||||
and remove items. Backed by a string list. Implement user selection in
|
and remove items. Backed by a string list. Implement user selection in
|
||||||
[select()]. */
|
[select()]. */
|
||||||
public abstract class ListGroupPreference extends PreferenceGroup
|
public abstract class ListGroupPreference<E> extends PreferenceGroup
|
||||||
{
|
{
|
||||||
boolean _attached = false;
|
boolean _attached = false;
|
||||||
List<String> _values;
|
List<E> _values;
|
||||||
/** The "add" button currently displayed. */
|
/** The "add" button currently displayed. */
|
||||||
AddButton _add_button = null;
|
AddButton _add_button = null;
|
||||||
|
|
||||||
@ -27,16 +27,13 @@ public abstract class ListGroupPreference extends PreferenceGroup
|
|||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
setOrderingAsAdded(true);
|
setOrderingAsAdded(true);
|
||||||
setLayoutResource(R.layout.pref_listgroup_group);
|
setLayoutResource(R.layout.pref_listgroup_group);
|
||||||
_values = new ArrayList<String>();
|
_values = new ArrayList<E>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Overrideable */
|
/** Overrideable */
|
||||||
|
|
||||||
/** The label to display on the item for a given value. */
|
/** The label to display on the item for a given value. */
|
||||||
String label_of_value(String value, int i)
|
abstract String label_of_value(E value, int i);
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Called every time the list changes and allows to change the "Add" button
|
/** Called every time the list changes and allows to change the "Add" button
|
||||||
appearance.
|
appearance.
|
||||||
@ -58,29 +55,34 @@ public abstract class ListGroupPreference extends PreferenceGroup
|
|||||||
|
|
||||||
/** Called when an item is added or modified. Returns [null] to cancel the
|
/** Called when an item is added or modified. Returns [null] to cancel the
|
||||||
action. */
|
action. */
|
||||||
abstract void select(SelectionCallback callback);
|
abstract void select(SelectionCallback<E> callback);
|
||||||
|
|
||||||
|
/** A separate class is used as the same serializer must be used in the
|
||||||
|
static context. See [Serializer] below. */
|
||||||
|
abstract Serializer<E> get_serializer();
|
||||||
|
|
||||||
/** Load/save utils */
|
/** Load/save utils */
|
||||||
|
|
||||||
/** Read a value saved by preference from a [SharedPreferences] object.
|
/** Read a value saved by preference from a [SharedPreferences] object.
|
||||||
|
[serializer] must be the same that is returned by [get_serializer()].
|
||||||
Returns [null] on error. */
|
Returns [null] on error. */
|
||||||
static List<String> load_from_preferences(String key,
|
static <E> List<E> load_from_preferences(String key,
|
||||||
SharedPreferences prefs, List<String> def)
|
SharedPreferences prefs, List<E> def, Serializer<E> serializer)
|
||||||
{
|
{
|
||||||
String s = prefs.getString(key, null);
|
String s = prefs.getString(key, null);
|
||||||
return (s != null) ? load_from_string(s) : def;
|
return (s != null) ? load_from_string(s, serializer) : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Decode a list of string previously encoded with [save_to_string]. Returns
|
/** Decode a list of string previously encoded with [save_to_string]. Returns
|
||||||
[null] on error. */
|
[null] on error. */
|
||||||
static List<String> load_from_string(String inp)
|
static <E> List<E> load_from_string(String inp, Serializer<E> serializer)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<String> l = new ArrayList<String>();
|
List<E> l = new ArrayList<E>();
|
||||||
JSONArray arr = new JSONArray(inp);
|
JSONArray arr = new JSONArray(inp);
|
||||||
for (int i = 0; i < arr.length(); i++)
|
for (int i = 0; i < arr.length(); i++)
|
||||||
l.add(arr.getString(i));
|
l.add(serializer.load_item(arr.get(i)));
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
catch (JSONException e)
|
catch (JSONException e)
|
||||||
@ -91,29 +93,32 @@ public abstract class ListGroupPreference extends PreferenceGroup
|
|||||||
|
|
||||||
/** Encode a list of string so it can be passed to
|
/** Encode a list of string so it can be passed to
|
||||||
[Preference.persistString()]. Decode with [load_from_string]. */
|
[Preference.persistString()]. Decode with [load_from_string]. */
|
||||||
static String save_to_string(List<String> l)
|
static <E> String save_to_string(List<E> items, Serializer<E> serializer)
|
||||||
{
|
{
|
||||||
return (new JSONArray(l)).toString();
|
List<Object> serialized_items = new ArrayList<Object>();
|
||||||
|
for (E it : items)
|
||||||
|
serialized_items.add(serializer.save_item(it));
|
||||||
|
return (new JSONArray(serialized_items)).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Protected API */
|
/** Protected API */
|
||||||
|
|
||||||
/** Set the values. If [persist] is [true], persist into the store. */
|
/** Set the values. If [persist] is [true], persist into the store. */
|
||||||
void set_values(List<String> vs, boolean persist)
|
void set_values(List<E> vs, boolean persist)
|
||||||
{
|
{
|
||||||
_values = vs;
|
_values = vs;
|
||||||
reattach();
|
reattach();
|
||||||
if (persist)
|
if (persist)
|
||||||
persistString(save_to_string(vs));
|
persistString(save_to_string(vs, get_serializer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_item(String v)
|
void add_item(E v)
|
||||||
{
|
{
|
||||||
_values.add(v);
|
_values.add(v);
|
||||||
set_values(_values, true);
|
set_values(_values, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void change_item(int i, String v)
|
void change_item(int i, E v)
|
||||||
{
|
{
|
||||||
_values.set(i, v);
|
_values.set(i, v);
|
||||||
set_values(_values, true);
|
set_values(_values, true);
|
||||||
@ -133,7 +138,7 @@ public abstract class ListGroupPreference extends PreferenceGroup
|
|||||||
String input = (restoreValue) ? getPersistedString(null) : (String)defaultValue;
|
String input = (restoreValue) ? getPersistedString(null) : (String)defaultValue;
|
||||||
if (input != null)
|
if (input != null)
|
||||||
{
|
{
|
||||||
List<String> values = load_from_string(input);
|
List<E> values = load_from_string(input, get_serializer());
|
||||||
if (values != null)
|
if (values != null)
|
||||||
set_values(values, false);
|
set_values(values, false);
|
||||||
}
|
}
|
||||||
@ -156,7 +161,7 @@ public abstract class ListGroupPreference extends PreferenceGroup
|
|||||||
removeAll();
|
removeAll();
|
||||||
boolean allow_remove_item = should_allow_remove_item();
|
boolean allow_remove_item = should_allow_remove_item();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (String v : _values)
|
for (E v : _values)
|
||||||
{
|
{
|
||||||
addPreference(this.new Item(getContext(), i, v, allow_remove_item));
|
addPreference(this.new Item(getContext(), i, v, allow_remove_item));
|
||||||
i++;
|
i++;
|
||||||
@ -168,10 +173,10 @@ public abstract class ListGroupPreference extends PreferenceGroup
|
|||||||
|
|
||||||
class Item extends Preference
|
class Item extends Preference
|
||||||
{
|
{
|
||||||
final String _value;
|
final E _value;
|
||||||
final int _index;
|
final int _index;
|
||||||
|
|
||||||
public Item(Context ctx, int index, String value, boolean allow_remove)
|
public Item(Context ctx, int index, E value, boolean allow_remove)
|
||||||
{
|
{
|
||||||
super(ctx);
|
super(ctx);
|
||||||
_value = value;
|
_value = value;
|
||||||
@ -185,8 +190,8 @@ public abstract class ListGroupPreference extends PreferenceGroup
|
|||||||
@Override
|
@Override
|
||||||
protected void onClick()
|
protected void onClick()
|
||||||
{
|
{
|
||||||
select(new SelectionCallback() {
|
select(new SelectionCallback<E>() {
|
||||||
public void select(String value)
|
public void select(E value)
|
||||||
{
|
{
|
||||||
change_item(_index, value);
|
change_item(_index, value);
|
||||||
}
|
}
|
||||||
@ -222,8 +227,8 @@ public abstract class ListGroupPreference extends PreferenceGroup
|
|||||||
@Override
|
@Override
|
||||||
protected void onClick()
|
protected void onClick()
|
||||||
{
|
{
|
||||||
select(new SelectionCallback() {
|
select(new SelectionCallback<E>() {
|
||||||
public void select(String value)
|
public void select(E value)
|
||||||
{
|
{
|
||||||
add_item(value);
|
add_item(value);
|
||||||
}
|
}
|
||||||
@ -231,8 +236,26 @@ public abstract class ListGroupPreference extends PreferenceGroup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface SelectionCallback
|
public interface SelectionCallback<E>
|
||||||
{
|
{
|
||||||
public void select(String value);
|
public void select(E value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Methods for serializing and deserializing abstract items.
|
||||||
|
[StringSerializer] is an implementation. */
|
||||||
|
public interface Serializer<E>
|
||||||
|
{
|
||||||
|
/** [obj] is an object returned by [save_item()]. */
|
||||||
|
E load_item(Object obj);
|
||||||
|
|
||||||
|
/** Serialize an item into JSON. Might return an object that can be inserted
|
||||||
|
in a [JSONArray]. */
|
||||||
|
Object save_item(E v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class StringSerializer implements Serializer<String>
|
||||||
|
{
|
||||||
|
public String load_item(Object obj) { return (String)obj; }
|
||||||
|
public Object save_item(String v) { return v; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user