From 283340f5dcd74f8a6fc3545f567cf1c2f6256318 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 25 Nov 2017 23:05:39 -0600 Subject: [PATCH] ConfigList: A better toggle switch Signed-off-by: Jason A. Donenfeld --- .../android/bindings/BindingAdapters.java | 13 ++++++ .../android/widgets/ToggleSwitch.java | 45 +++++++++++-------- app/src/main/res/layout/config_list_item.xml | 9 ++-- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/com/wireguard/android/bindings/BindingAdapters.java b/app/src/main/java/com/wireguard/android/bindings/BindingAdapters.java index 621543aa..fffe191a 100644 --- a/app/src/main/java/com/wireguard/android/bindings/BindingAdapters.java +++ b/app/src/main/java/com/wireguard/android/bindings/BindingAdapters.java @@ -10,6 +10,7 @@ import android.widget.ListView; import android.widget.TextView; import com.wireguard.android.R; +import com.wireguard.android.widgets.ToggleSwitch; /** * Static methods for use by generated code in the Android data binding library. @@ -17,6 +18,11 @@ import com.wireguard.android.R; @SuppressWarnings("unused") public final class BindingAdapters { + @BindingAdapter({"app:checked"}) + public static void setChecked(final ToggleSwitch view, final boolean checked) { + view.setCheckedInternal(checked); + } + @BindingAdapter({"filter"}) public static void setFilter(final TextView view, final InputFilter filter) { view.setFilters(new InputFilter[]{filter}); @@ -99,6 +105,13 @@ public final class BindingAdapters { adapter.setMap(newMap); } + @BindingAdapter({"app:onBeforeCheckedChanged"}) + public static void setOnBeforeCheckedChanged(final ToggleSwitch view, + final ToggleSwitch.OnBeforeCheckedChangeListener + listener) { + view.setOnBeforeCheckedChangeListener(listener); + } + @BindingAdapter({"android:textStyle"}) public static void setTextStyle(final TextView view, final Typeface typeface) { view.setTypeface(typeface); diff --git a/app/src/main/java/com/wireguard/android/widgets/ToggleSwitch.java b/app/src/main/java/com/wireguard/android/widgets/ToggleSwitch.java index 25bb1092..667cfe53 100644 --- a/app/src/main/java/com/wireguard/android/widgets/ToggleSwitch.java +++ b/app/src/main/java/com/wireguard/android/widgets/ToggleSwitch.java @@ -21,43 +21,52 @@ import android.util.AttributeSet; import android.widget.Switch; public class ToggleSwitch extends Switch { + private boolean hasPendingStateChange; + private OnBeforeCheckedChangeListener listener; - private ToggleSwitch.OnBeforeCheckedChangeListener mOnBeforeListener; - - public static interface OnBeforeCheckedChangeListener { - public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked); + public interface OnBeforeCheckedChangeListener { + void onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked); } - public ToggleSwitch(Context context) { + public ToggleSwitch(final Context context) { super(context); } - public ToggleSwitch(Context context, AttributeSet attrs) { + public ToggleSwitch(final Context context, final AttributeSet attrs) { super(context, attrs); } - public ToggleSwitch(Context context, AttributeSet attrs, int defStyleAttr) { + public ToggleSwitch(final Context context, final AttributeSet attrs, final int defStyleAttr) { super(context, attrs, defStyleAttr); } - public ToggleSwitch(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + public ToggleSwitch(final Context context, final AttributeSet attrs, final int defStyleAttr, + final int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } - public void setOnBeforeCheckedChangeListener(OnBeforeCheckedChangeListener listener) { - mOnBeforeListener = listener; + public void setOnBeforeCheckedChangeListener(final OnBeforeCheckedChangeListener listener) { + this.listener = listener; } @Override - public void setChecked(boolean checked) { - if (mOnBeforeListener != null - && mOnBeforeListener.onBeforeCheckedChanged(this, checked)) { - return; + public void setChecked(final boolean checked) { + if (listener != null) { + if (!isEnabled()) + return; + setEnabled(false); + hasPendingStateChange = true; + listener.onBeforeCheckedChanged(this, checked); + } else { + super.setChecked(checked); + } + } + + public void setCheckedInternal(final boolean checked) { + if (hasPendingStateChange) { + setEnabled(true); + hasPendingStateChange = false; } super.setChecked(checked); } - - public void setCheckedInternal(boolean checked) { - super.setChecked(checked); - } } diff --git a/app/src/main/res/layout/config_list_item.xml b/app/src/main/res/layout/config_list_item.xml index 87380dee..207f95ef 100644 --- a/app/src/main/res/layout/config_list_item.xml +++ b/app/src/main/res/layout/config_list_item.xml @@ -1,5 +1,6 @@ - + @@ -35,13 +36,13 @@ android:text="@{key}" android:textStyle="@{item.primary ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT}" /> - + app:checked="@{item.enabled}" + app:onBeforeCheckedChanged="@{(v, checked) -> checked ? VpnService.instance.enable(item.name) : VpnService.instance.disable(item.name)}" />