ConfigList: A better toggle switch

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Samuel Holland 2017-11-25 23:05:39 -06:00
parent 666dc25cb0
commit 283340f5dc
3 changed files with 45 additions and 22 deletions

View File

@ -10,6 +10,7 @@ import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import com.wireguard.android.R; import com.wireguard.android.R;
import com.wireguard.android.widgets.ToggleSwitch;
/** /**
* Static methods for use by generated code in the Android data binding library. * Static methods for use by generated code in the Android data binding library.
@ -17,6 +18,11 @@ import com.wireguard.android.R;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class BindingAdapters { public final class BindingAdapters {
@BindingAdapter({"app:checked"})
public static void setChecked(final ToggleSwitch view, final boolean checked) {
view.setCheckedInternal(checked);
}
@BindingAdapter({"filter"}) @BindingAdapter({"filter"})
public static void setFilter(final TextView view, final InputFilter filter) { public static void setFilter(final TextView view, final InputFilter filter) {
view.setFilters(new InputFilter[]{filter}); view.setFilters(new InputFilter[]{filter});
@ -99,6 +105,13 @@ public final class BindingAdapters {
adapter.setMap(newMap); adapter.setMap(newMap);
} }
@BindingAdapter({"app:onBeforeCheckedChanged"})
public static void setOnBeforeCheckedChanged(final ToggleSwitch view,
final ToggleSwitch.OnBeforeCheckedChangeListener
listener) {
view.setOnBeforeCheckedChangeListener(listener);
}
@BindingAdapter({"android:textStyle"}) @BindingAdapter({"android:textStyle"})
public static void setTextStyle(final TextView view, final Typeface typeface) { public static void setTextStyle(final TextView view, final Typeface typeface) {
view.setTypeface(typeface); view.setTypeface(typeface);

View File

@ -21,43 +21,52 @@ import android.util.AttributeSet;
import android.widget.Switch; import android.widget.Switch;
public class ToggleSwitch extends Switch { public class ToggleSwitch extends Switch {
private boolean hasPendingStateChange;
private OnBeforeCheckedChangeListener listener;
private ToggleSwitch.OnBeforeCheckedChangeListener mOnBeforeListener; public interface OnBeforeCheckedChangeListener {
void onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked);
public static interface OnBeforeCheckedChangeListener {
public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked);
} }
public ToggleSwitch(Context context) { public ToggleSwitch(final Context context) {
super(context); super(context);
} }
public ToggleSwitch(Context context, AttributeSet attrs) { public ToggleSwitch(final Context context, final AttributeSet attrs) {
super(context, 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); 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); super(context, attrs, defStyleAttr, defStyleRes);
} }
public void setOnBeforeCheckedChangeListener(OnBeforeCheckedChangeListener listener) { public void setOnBeforeCheckedChangeListener(final OnBeforeCheckedChangeListener listener) {
mOnBeforeListener = listener; this.listener = listener;
} }
@Override @Override
public void setChecked(boolean checked) { public void setChecked(final boolean checked) {
if (mOnBeforeListener != null if (listener != null) {
&& mOnBeforeListener.onBeforeCheckedChanged(this, checked)) { if (!isEnabled())
return; 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); super.setChecked(checked);
} }
public void setCheckedInternal(boolean checked) {
super.setChecked(checked);
}
} }

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data> <data>
@ -35,13 +36,13 @@
android:text="@{key}" android:text="@{key}"
android:textStyle="@{item.primary ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT}" /> android:textStyle="@{item.primary ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT}" />
<Switch <com.wireguard.android.widgets.ToggleSwitch
android:id="@+id/config_switch" android:id="@+id/config_switch"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/config_name" android:layout_alignBaseline="@+id/config_name"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:checked="@{item.enabled}" app:checked="@{item.enabled}"
android:onCheckedChanged="@{(v, checked) -> checked ? VpnService.instance.enable(item.name) : VpnService.instance.disable(item.name)}" /> app:onBeforeCheckedChanged="@{(v, checked) -> checked ? VpnService.instance.enable(item.name) : VpnService.instance.disable(item.name)}" />
</RelativeLayout> </RelativeLayout>
</layout> </layout>