From 0269cd65ea57a5046783bcc88243f8f2407952d8 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Tue, 8 Aug 2023 17:58:27 +0200 Subject: [PATCH] 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. --- .../CustomExtraKeysPreference.java | 13 ++- srcs/juloo.keyboard2/LayoutsPreference.java | 9 +- srcs/juloo.keyboard2/ListGroupPreference.java | 83 ++++++++++++------- 3 files changed, 70 insertions(+), 35 deletions(-) diff --git a/srcs/juloo.keyboard2/CustomExtraKeysPreference.java b/srcs/juloo.keyboard2/CustomExtraKeysPreference.java index 7bbc449..465b2e7 100644 --- a/srcs/juloo.keyboard2/CustomExtraKeysPreference.java +++ b/srcs/juloo.keyboard2/CustomExtraKeysPreference.java @@ -17,10 +17,12 @@ import org.json.JSONException; /** 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. */ -public class CustomExtraKeysPreference extends ListGroupPreference +public class CustomExtraKeysPreference extends ListGroupPreference { /** This pref stores a list of strings encoded as JSON. */ static final String KEY = "custom_extra_keys"; + static final ListGroupPreference.Serializer SERIALIZER = + new ListGroupPreference.StringSerializer(); public CustomExtraKeysPreference(Context context, AttributeSet attrs) { @@ -31,7 +33,7 @@ public class CustomExtraKeysPreference extends ListGroupPreference public static List get(SharedPreferences prefs) { List kvs = new ArrayList(); - List key_names = load_from_preferences(KEY, prefs, null); + List key_names = load_from_preferences(KEY, prefs, null, SERIALIZER); if (key_names != null) { for (String key_name : key_names) @@ -40,8 +42,10 @@ public class CustomExtraKeysPreference extends ListGroupPreference return kvs; } + String label_of_value(String value, int i) { return value; } + @Override - void select(final SelectionCallback callback) + void select(final SelectionCallback callback) { new AlertDialog.Builder(getContext()) .setView(R.layout.custom_extra_key_add_dialog) @@ -58,4 +62,7 @@ public class CustomExtraKeysPreference extends ListGroupPreference .setIcon(android.R.drawable.ic_dialog_alert) .show(); } + + @Override + Serializer get_serializer() { return SERIALIZER; } } diff --git a/srcs/juloo.keyboard2/LayoutsPreference.java b/srcs/juloo.keyboard2/LayoutsPreference.java index 4ce8dfa..a891ed8 100644 --- a/srcs/juloo.keyboard2/LayoutsPreference.java +++ b/srcs/juloo.keyboard2/LayoutsPreference.java @@ -13,10 +13,12 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -public class LayoutsPreference extends ListGroupPreference +public class LayoutsPreference extends ListGroupPreference { static final String KEY = "layouts"; static final List DEFAULT = Collections.singletonList("system"); + static final ListGroupPreference.Serializer SERIALIZER = + new ListGroupPreference.StringSerializer(); /** Layout names as stored in the preferences. */ List _layout_names; @@ -34,7 +36,7 @@ public class LayoutsPreference extends ListGroupPreference public static List load_from_preferences(SharedPreferences prefs) { - return load_from_preferences(KEY, prefs, DEFAULT); + return load_from_preferences(KEY, prefs, DEFAULT, SERIALIZER); } @Override @@ -67,6 +69,9 @@ public class LayoutsPreference extends ListGroupPreference return (_values.size() > 1); } + @Override + Serializer get_serializer() { return SERIALIZER; } + void select(final SelectionCallback callback) { ArrayAdapter layouts = new ArrayAdapter(getContext(), android.R.layout.simple_list_item_1, _layout_display_names); diff --git a/srcs/juloo.keyboard2/ListGroupPreference.java b/srcs/juloo.keyboard2/ListGroupPreference.java index 5631aed..9136a0c 100644 --- a/srcs/juloo.keyboard2/ListGroupPreference.java +++ b/srcs/juloo.keyboard2/ListGroupPreference.java @@ -15,10 +15,10 @@ import org.json.JSONException; /** 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 [select()]. */ -public abstract class ListGroupPreference extends PreferenceGroup +public abstract class ListGroupPreference extends PreferenceGroup { boolean _attached = false; - List _values; + List _values; /** The "add" button currently displayed. */ AddButton _add_button = null; @@ -27,16 +27,13 @@ public abstract class ListGroupPreference extends PreferenceGroup super(context, attrs); setOrderingAsAdded(true); setLayoutResource(R.layout.pref_listgroup_group); - _values = new ArrayList(); + _values = new ArrayList(); } /** Overrideable */ /** The label to display on the item for a given value. */ - String label_of_value(String value, int i) - { - return value; - } + abstract String label_of_value(E value, int i); /** Called every time the list changes and allows to change the "Add" button appearance. @@ -58,29 +55,34 @@ public abstract class ListGroupPreference extends PreferenceGroup /** Called when an item is added or modified. Returns [null] to cancel the action. */ - abstract void select(SelectionCallback callback); + abstract void select(SelectionCallback callback); + + /** A separate class is used as the same serializer must be used in the + static context. See [Serializer] below. */ + abstract Serializer get_serializer(); /** Load/save utils */ /** 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. */ - static List load_from_preferences(String key, - SharedPreferences prefs, List def) + static List load_from_preferences(String key, + SharedPreferences prefs, List def, Serializer serializer) { 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 [null] on error. */ - static List load_from_string(String inp) + static List load_from_string(String inp, Serializer serializer) { try { - List l = new ArrayList(); + List l = new ArrayList(); JSONArray arr = new JSONArray(inp); for (int i = 0; i < arr.length(); i++) - l.add(arr.getString(i)); + l.add(serializer.load_item(arr.get(i))); return l; } catch (JSONException e) @@ -91,29 +93,32 @@ public abstract class ListGroupPreference extends PreferenceGroup /** Encode a list of string so it can be passed to [Preference.persistString()]. Decode with [load_from_string]. */ - static String save_to_string(List l) + static String save_to_string(List items, Serializer serializer) { - return (new JSONArray(l)).toString(); + List serialized_items = new ArrayList(); + for (E it : items) + serialized_items.add(serializer.save_item(it)); + return (new JSONArray(serialized_items)).toString(); } /** Protected API */ /** Set the values. If [persist] is [true], persist into the store. */ - void set_values(List vs, boolean persist) + void set_values(List vs, boolean persist) { _values = vs; reattach(); 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); set_values(_values, true); } - void change_item(int i, String v) + void change_item(int i, E v) { _values.set(i, v); set_values(_values, true); @@ -133,7 +138,7 @@ public abstract class ListGroupPreference extends PreferenceGroup String input = (restoreValue) ? getPersistedString(null) : (String)defaultValue; if (input != null) { - List values = load_from_string(input); + List values = load_from_string(input, get_serializer()); if (values != null) set_values(values, false); } @@ -156,7 +161,7 @@ public abstract class ListGroupPreference extends PreferenceGroup removeAll(); boolean allow_remove_item = should_allow_remove_item(); int i = 0; - for (String v : _values) + for (E v : _values) { addPreference(this.new Item(getContext(), i, v, allow_remove_item)); i++; @@ -168,10 +173,10 @@ public abstract class ListGroupPreference extends PreferenceGroup class Item extends Preference { - final String _value; + final E _value; 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); _value = value; @@ -185,8 +190,8 @@ public abstract class ListGroupPreference extends PreferenceGroup @Override protected void onClick() { - select(new SelectionCallback() { - public void select(String value) + select(new SelectionCallback() { + public void select(E value) { change_item(_index, value); } @@ -222,8 +227,8 @@ public abstract class ListGroupPreference extends PreferenceGroup @Override protected void onClick() { - select(new SelectionCallback() { - public void select(String value) + select(new SelectionCallback() { + public void select(E value) { add_item(value); } @@ -231,8 +236,26 @@ public abstract class ListGroupPreference extends PreferenceGroup } } - public interface SelectionCallback + public interface SelectionCallback { - public void select(String value); + public void select(E value); + } + + /** Methods for serializing and deserializing abstract items. + [StringSerializer] is an implementation. */ + public interface Serializer + { + /** [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 + { + public String load_item(Object obj) { return (String)obj; } + public Object save_item(String v) { return v; } } }