forked from extern/Unexpected-Keyboard
Refactor: Split out ListGroupPreference
Split out the implementation of a string-list preference from CustomExtraKeysPreference. Allows to share the implementation with future preferences.
This commit is contained in:
parent
0a114bd2bc
commit
0856fb4e31
@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal">
|
|
||||||
<Button android:id="@+id/btn_custom_extra_key_remove" android:layout_width="@dimen/pref_button_size" android:layout_height="@dimen/pref_button_size" android:layout_gravity="center" android:background="@android:drawable/ic_menu_close_clear_cancel"/>
|
|
||||||
</LinearLayout>
|
|
3
res/layout/pref_listgroup_group.xml
Normal file
3
res/layout/pref_listgroup_group.xml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center">
|
||||||
|
</LinearLayout>
|
4
res/layout/pref_listgroup_item_widget.xml
Normal file
4
res/layout/pref_listgroup_item_widget.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal">
|
||||||
|
<Button android:id="@+id/pref_listgroup_remove_btn" android:layout_width="@dimen/pref_button_size" android:layout_height="@dimen/pref_button_size" android:layout_gravity="center" android:background="@android:drawable/ic_menu_close_clear_cancel"/>
|
||||||
|
</LinearLayout>
|
@ -7,7 +7,9 @@
|
|||||||
<ListPreference android:key="show_numpad" android:title="@string/pref_show_numpad_title" android:summary="%s" android:defaultValue="1" android:entries="@array/pref_show_numpad_entries" android:entryValues="@array/pref_show_numpad_values"/>
|
<ListPreference android:key="show_numpad" android:title="@string/pref_show_numpad_title" android:summary="%s" android:defaultValue="1" android:entries="@array/pref_show_numpad_entries" android:entryValues="@array/pref_show_numpad_values"/>
|
||||||
<CheckBoxPreference android:key="number_row" android:title="@string/pref_number_row_title" android:summary="@string/pref_number_row_summary" android:defaultValue="false"/>
|
<CheckBoxPreference android:key="number_row" android:title="@string/pref_number_row_title" android:summary="@string/pref_number_row_summary" android:defaultValue="false"/>
|
||||||
<PreferenceScreen android:title="@string/pref_extra_keys_title">
|
<PreferenceScreen android:title="@string/pref_extra_keys_title">
|
||||||
<juloo.keyboard2.CustomExtraKeysPreference android:title="@string/pref_extra_keys_custom"/>
|
<PreferenceCategory android:title="@string/pref_extra_keys_custom">
|
||||||
|
<juloo.keyboard2.CustomExtraKeysPreference/>
|
||||||
|
</PreferenceCategory>
|
||||||
<juloo.keyboard2.ExtraKeysPreference android:title="@string/pref_extra_keys_internal"/>
|
<juloo.keyboard2.ExtraKeysPreference android:title="@string/pref_extra_keys_internal"/>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
<ListPreference android:key="numpad_layout" android:title="@string/pref_numpad_layout" android:summary="%s" android:defaultValue="high_first" android:entries="@array/pref_numpad_layout_entries" android:entryValues="@array/pref_numpad_layout_values"/>
|
<ListPreference android:key="numpad_layout" android:title="@string/pref_numpad_layout" android:summary="%s" android:defaultValue="high_first" android:entries="@array/pref_numpad_layout_entries" android:entryValues="@array/pref_numpad_layout_values"/>
|
||||||
|
@ -17,161 +17,45 @@ 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 PreferenceCategory
|
public class CustomExtraKeysPreference extends ListGroupPreference
|
||||||
{
|
{
|
||||||
/** This pref stores a list of strings encoded as JSON. */
|
/** This pref stores a list of strings encoded as JSON. */
|
||||||
static String KEY = "custom_extra_keys";
|
static final String KEY = "custom_extra_keys";
|
||||||
|
|
||||||
boolean _attached = false;
|
|
||||||
/** Mutable. This is the list of the key strings, not the key names. */
|
|
||||||
List<String> _keys;
|
|
||||||
|
|
||||||
public CustomExtraKeysPreference(Context context, AttributeSet attrs)
|
public CustomExtraKeysPreference(Context context, AttributeSet attrs)
|
||||||
{
|
{
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
setKey(KEY);
|
setKey(KEY);
|
||||||
setOrderingAsAdded(true);
|
|
||||||
_keys = new ArrayList<String>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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>();
|
||||||
String inp = prefs.getString(KEY, null);
|
List<String> key_names = load_from_preferences(KEY, prefs, null);
|
||||||
if (inp != null)
|
if (key_names != null)
|
||||||
for (String key_name : load_from_string(inp))
|
{
|
||||||
|
for (String key_name : key_names)
|
||||||
kvs.add(KeyValue.makeStringKey(key_name));
|
kvs.add(KeyValue.makeStringKey(key_name));
|
||||||
|
}
|
||||||
return kvs;
|
return kvs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onSetInitialValue(boolean restoreValue, Object defaultValue)
|
void select(final SelectionCallback callback)
|
||||||
{
|
{
|
||||||
if (restoreValue)
|
new AlertDialog.Builder(getContext())
|
||||||
{
|
.setView(R.layout.custom_extra_key_add_dialog)
|
||||||
String persisted = getPersistedString(null);
|
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
|
||||||
if (persisted != null)
|
public void onClick(DialogInterface dialog, int which)
|
||||||
set_keys(load_from_string(persisted), false);
|
{
|
||||||
}
|
EditText input = (EditText)((AlertDialog)dialog).findViewById(R.id.key_name);
|
||||||
else if (defaultValue != null)
|
final String k = input.getText().toString();
|
||||||
set_keys(load_from_string((String)defaultValue), false);
|
if (!k.equals(""))
|
||||||
}
|
callback.select(k);
|
||||||
|
}
|
||||||
@Override
|
})
|
||||||
protected void onAttachedToActivity()
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
{
|
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||||
super.onAttachedToActivity();
|
.show();
|
||||||
if (_attached)
|
|
||||||
return;
|
|
||||||
_attached = true;
|
|
||||||
reattach();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reattach()
|
|
||||||
{
|
|
||||||
removeAll();
|
|
||||||
for (String k : _keys)
|
|
||||||
addPreference(this.new CustomExtraKey(getContext(), k));
|
|
||||||
addPreference(this.new AddButton(getContext()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_keys(List<String> v, boolean persist)
|
|
||||||
{
|
|
||||||
_keys = v;
|
|
||||||
reattach();
|
|
||||||
if (persist)
|
|
||||||
persistString(save_to_string(_keys));
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_key(String k)
|
|
||||||
{
|
|
||||||
_keys.add(k);
|
|
||||||
set_keys(_keys, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove_key(String k)
|
|
||||||
{
|
|
||||||
_keys.remove(k);
|
|
||||||
set_keys(_keys, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static String save_to_string(List<String> keys)
|
|
||||||
{
|
|
||||||
return (new JSONArray(keys)).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<String> load_from_string(String inp)
|
|
||||||
{
|
|
||||||
List<String> keys = new ArrayList<String>();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
JSONArray arr = new JSONArray(inp);
|
|
||||||
for (int i = 0; i < arr.length(); i++)
|
|
||||||
keys.add(arr.getString(i));
|
|
||||||
}
|
|
||||||
catch (JSONException e)
|
|
||||||
{
|
|
||||||
Logs.err_load_custom_extra_keys(e);
|
|
||||||
}
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A preference with no key that is only intended to be rendered. */
|
|
||||||
final class CustomExtraKey extends Preference implements View.OnClickListener
|
|
||||||
{
|
|
||||||
String _key;
|
|
||||||
|
|
||||||
public CustomExtraKey(Context ctx, String key)
|
|
||||||
{
|
|
||||||
super(ctx);
|
|
||||||
_key = key;
|
|
||||||
setTitle(key);
|
|
||||||
setPersistent(false);
|
|
||||||
setWidgetLayoutResource(R.layout.custom_extra_key_widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Remove-button listener. */
|
|
||||||
@Override
|
|
||||||
public void onClick(View _v)
|
|
||||||
{
|
|
||||||
CustomExtraKeysPreference.this.remove_key(_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View onCreateView(ViewGroup parent)
|
|
||||||
{
|
|
||||||
View v = super.onCreateView(parent);
|
|
||||||
v.findViewById(R.id.btn_custom_extra_key_remove).setOnClickListener(this);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class AddButton extends Preference
|
|
||||||
{
|
|
||||||
public AddButton(Context ctx)
|
|
||||||
{
|
|
||||||
super(ctx);
|
|
||||||
setPersistent(false);
|
|
||||||
setLayoutResource(R.layout.custom_extra_key_add);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onClick()
|
|
||||||
{
|
|
||||||
new AlertDialog.Builder(getContext())
|
|
||||||
.setView(R.layout.custom_extra_key_add_dialog)
|
|
||||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
|
|
||||||
public void onClick(DialogInterface dialog, int which)
|
|
||||||
{
|
|
||||||
EditText input = (EditText)((AlertDialog)dialog).findViewById(R.id.key_name);
|
|
||||||
String k = input.getText().toString();
|
|
||||||
if (!k.equals(""))
|
|
||||||
CustomExtraKeysPreference.this.add_key(k);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
|
||||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
193
srcs/juloo.keyboard2/ListGroupPreference.java
Normal file
193
srcs/juloo.keyboard2/ListGroupPreference.java
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
package juloo.keyboard2;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.preference.PreferenceGroup;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
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
|
||||||
|
{
|
||||||
|
boolean _attached = false;
|
||||||
|
List<String> _values;
|
||||||
|
|
||||||
|
public ListGroupPreference(Context context, AttributeSet attrs)
|
||||||
|
{
|
||||||
|
super(context, attrs);
|
||||||
|
setOrderingAsAdded(true);
|
||||||
|
setLayoutResource(R.layout.pref_listgroup_group);
|
||||||
|
_values = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Overrideable */
|
||||||
|
|
||||||
|
/** The label to display on the item for a given value. */
|
||||||
|
String label_of_value(String value, int i)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called when an item is added or modified. Returns [null] to cancel the
|
||||||
|
action. */
|
||||||
|
abstract void select(SelectionCallback callback);
|
||||||
|
|
||||||
|
/** Load/save utils */
|
||||||
|
|
||||||
|
/** Read a value saved by preference from a [SharedPreferences] object.
|
||||||
|
Returns [null] on error. */
|
||||||
|
static List<String> load_from_preferences(String key,
|
||||||
|
SharedPreferences prefs, List<String> def)
|
||||||
|
{
|
||||||
|
String s = prefs.getString(key, null);
|
||||||
|
return (s != null) ? load_from_string(s) : def;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Decode a list of string previously encoded with [save_to_string]. Returns
|
||||||
|
[null] on error. */
|
||||||
|
static List<String> load_from_string(String inp)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<String> l = new ArrayList<String>();
|
||||||
|
JSONArray arr = new JSONArray(inp);
|
||||||
|
for (int i = 0; i < arr.length(); i++)
|
||||||
|
l.add(arr.getString(i));
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
catch (JSONException e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Encode a list of string so it can be passed to
|
||||||
|
[Preference.persistString()]. Decode with [load_from_string]. */
|
||||||
|
static String save_to_string(List<String> l)
|
||||||
|
{
|
||||||
|
return (new JSONArray(l)).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Protected API */
|
||||||
|
|
||||||
|
/** Set the values. If [persist] is [true], persist into the store. */
|
||||||
|
void set_values(List<String> vs, boolean persist)
|
||||||
|
{
|
||||||
|
_values = vs;
|
||||||
|
reattach();
|
||||||
|
if (persist)
|
||||||
|
persistString(save_to_string(vs));
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_item(String v)
|
||||||
|
{
|
||||||
|
_values.add(v);
|
||||||
|
set_values(_values, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove_item(String v)
|
||||||
|
{
|
||||||
|
_values.remove(v);
|
||||||
|
set_values(_values, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Internal */
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSetInitialValue(boolean restoreValue, Object defaultValue)
|
||||||
|
{
|
||||||
|
String input = (restoreValue) ? getPersistedString(null) : (String)defaultValue;
|
||||||
|
if (input != null)
|
||||||
|
{
|
||||||
|
List<String> values = load_from_string(input);
|
||||||
|
if (values != null)
|
||||||
|
set_values(values, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToActivity()
|
||||||
|
{
|
||||||
|
super.onAttachedToActivity();
|
||||||
|
if (_attached)
|
||||||
|
return;
|
||||||
|
_attached = true;
|
||||||
|
reattach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reattach()
|
||||||
|
{
|
||||||
|
removeAll();
|
||||||
|
int i = 0;
|
||||||
|
for (String v : _values)
|
||||||
|
{
|
||||||
|
Item item = this.new Item(getContext(), v);
|
||||||
|
item.setTitle(label_of_value(v, i));
|
||||||
|
addPreference(item);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
addPreference(this.new AddButton(getContext()));
|
||||||
|
}
|
||||||
|
|
||||||
|
class Item extends Preference
|
||||||
|
{
|
||||||
|
final String _value;
|
||||||
|
|
||||||
|
public Item(Context ctx, String value)
|
||||||
|
{
|
||||||
|
super(ctx);
|
||||||
|
_value = value;
|
||||||
|
setPersistent(false);
|
||||||
|
setWidgetLayoutResource(R.layout.pref_listgroup_item_widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected View onCreateView(ViewGroup parent)
|
||||||
|
{
|
||||||
|
View v = super.onCreateView(parent);
|
||||||
|
v.findViewById(R.id.pref_listgroup_remove_btn)
|
||||||
|
.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View _v)
|
||||||
|
{
|
||||||
|
remove_item(_value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class AddButton extends Preference
|
||||||
|
{
|
||||||
|
public AddButton(Context ctx)
|
||||||
|
{
|
||||||
|
super(ctx);
|
||||||
|
setPersistent(false);
|
||||||
|
setLayoutResource(R.layout.pref_listgroup_add_btn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onClick()
|
||||||
|
{
|
||||||
|
select(new SelectionCallback() {
|
||||||
|
public void select(String value)
|
||||||
|
{
|
||||||
|
add_item(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface SelectionCallback
|
||||||
|
{
|
||||||
|
public void select(String value);
|
||||||
|
}
|
||||||
|
}
|
@ -26,9 +26,4 @@ public final class Logs
|
|||||||
_debug_logs.println("swapEnterActionKey: "+conf.swapEnterActionKey);
|
_debug_logs.println("swapEnterActionKey: "+conf.swapEnterActionKey);
|
||||||
_debug_logs.println("actionLabel: "+conf.actionLabel);
|
_debug_logs.println("actionLabel: "+conf.actionLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void err_load_custom_extra_keys(JSONException e)
|
|
||||||
{
|
|
||||||
Log.e(TAG, "Failed to read custom extra keys from preferences", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user