Show different color for multiselection
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
d5cde43158
commit
75dfa0643b
@ -41,6 +41,7 @@ import com.wireguard.android.model.Tunnel;
|
|||||||
import com.wireguard.android.util.ExceptionLoggers;
|
import com.wireguard.android.util.ExceptionLoggers;
|
||||||
import com.wireguard.android.util.ObservableSortedKeyedList;
|
import com.wireguard.android.util.ObservableSortedKeyedList;
|
||||||
import com.wireguard.android.widget.MonkeyedSnackbar;
|
import com.wireguard.android.widget.MonkeyedSnackbar;
|
||||||
|
import com.wireguard.android.widget.MultiselectableRelativeLayout;
|
||||||
import com.wireguard.android.widget.fab.FloatingActionsMenuRecyclerViewScrollListener;
|
import com.wireguard.android.widget.fab.FloatingActionsMenuRecyclerViewScrollListener;
|
||||||
import com.wireguard.config.Config;
|
import com.wireguard.config.Config;
|
||||||
|
|
||||||
@ -263,30 +264,20 @@ public class TunnelListFragment extends BaseFragment {
|
|||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MultiselectableRelativeLayout viewForTunnel(final Tunnel tunnel, final List tunnels) {
|
||||||
|
return (MultiselectableRelativeLayout)binding.tunnelList.findViewHolderForAdapterPosition(tunnels.indexOf(tunnel)).itemView;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSelectedTunnelChanged(@Nullable final Tunnel oldTunnel, @Nullable final Tunnel newTunnel) {
|
public void onSelectedTunnelChanged(@Nullable final Tunnel oldTunnel, @Nullable final Tunnel newTunnel) {
|
||||||
if (binding == null)
|
if (binding == null)
|
||||||
return;
|
return;
|
||||||
Application.getTunnelManager().getTunnels().thenAccept(tunnels -> {
|
Application.getTunnelManager().getTunnels().thenAccept(tunnels -> {
|
||||||
if (newTunnel != null)
|
if (newTunnel != null)
|
||||||
binding.tunnelList.findViewHolderForAdapterPosition(tunnels.indexOf(newTunnel)).itemView.setActivated(true);
|
viewForTunnel(newTunnel, tunnels).setSingleSelected(true);
|
||||||
if (oldTunnel != null)
|
if (oldTunnel != null)
|
||||||
binding.tunnelList.findViewHolderForAdapterPosition(tunnels.indexOf(oldTunnel)).itemView.setActivated(false);
|
viewForTunnel(oldTunnel, tunnels).setSingleSelected(false);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Alternative 1: results in sluggish change:
|
|
||||||
|
|
||||||
if (binding.tunnelList.getAdapter() == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
* Alternative 2: results in overly quick change:
|
|
||||||
|
|
||||||
binding.tunnelList.getAdapter().notifyDataSetChanged();
|
|
||||||
|
|
||||||
* Hence, we go with the above.
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onTunnelDeletionFinished(final Integer count, @Nullable final Throwable throwable) {
|
private void onTunnelDeletionFinished(final Integer count, @Nullable final Throwable throwable) {
|
||||||
@ -373,10 +364,9 @@ public class TunnelListFragment extends BaseFragment {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (actionMode != null)
|
if (actionMode != null)
|
||||||
binding.getRoot().setActivated(actionModeListener.checkedItems.contains(position));
|
((MultiselectableRelativeLayout)binding.getRoot()).setMultiSelected(actionModeListener.checkedItems.contains(position));
|
||||||
else
|
else
|
||||||
binding.getRoot().setActivated(getSelectedTunnel() == tunnel);
|
((MultiselectableRelativeLayout)binding.getRoot()).setSingleSelected(getSelectedTunnel() == tunnel);
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,7 +423,6 @@ public class TunnelListFragment extends BaseFragment {
|
|||||||
public void onDestroyActionMode(final ActionMode mode) {
|
public void onDestroyActionMode(final ActionMode mode) {
|
||||||
actionMode = null;
|
actionMode = null;
|
||||||
resources = null;
|
resources = null;
|
||||||
|
|
||||||
checkedItems.clear();
|
checkedItems.clear();
|
||||||
binding.tunnelList.getAdapter().notifyDataSetChanged();
|
binding.tunnelList.getAdapter().notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.wireguard.android.widget;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
|
||||||
|
import com.wireguard.android.R;
|
||||||
|
|
||||||
|
public class MultiselectableRelativeLayout extends RelativeLayout {
|
||||||
|
public MultiselectableRelativeLayout(final Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
public MultiselectableRelativeLayout(final Context context, final AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
public MultiselectableRelativeLayout(final Context context, final AttributeSet attrs, final int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
public MultiselectableRelativeLayout(final Context context, final AttributeSet attrs, final int defStyleAttr, final int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int[] STATE_MULTISELECTED = { R.attr.state_multiselected };
|
||||||
|
|
||||||
|
private boolean multiselected;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int[] onCreateDrawableState(final int extraSpace) {
|
||||||
|
if (multiselected) {
|
||||||
|
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
|
||||||
|
mergeDrawableStates(drawableState, STATE_MULTISELECTED);
|
||||||
|
return drawableState;
|
||||||
|
}
|
||||||
|
return super.onCreateDrawableState(extraSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMultiSelected(final boolean on) {
|
||||||
|
if (!multiselected) {
|
||||||
|
multiselected = true;
|
||||||
|
refreshDrawableState();
|
||||||
|
}
|
||||||
|
setActivated(on);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSingleSelected(final boolean on) {
|
||||||
|
if (multiselected) {
|
||||||
|
multiselected = false;
|
||||||
|
refreshDrawableState();
|
||||||
|
}
|
||||||
|
setActivated(on);
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
<item>
|
<item>
|
||||||
<selector>
|
<selector>
|
||||||
<item android:state_activated="true">
|
<item app:state_multiselected="true" android:state_activated="true">
|
||||||
|
<color android:color="?android:attr/colorControlActivated" />
|
||||||
|
</item>
|
||||||
|
<item app:state_multiselected="false" android:state_activated="true">
|
||||||
<color android:color="?android:attr/colorControlHighlight" />
|
<color android:color="?android:attr/colorControlHighlight" />
|
||||||
<!-- TODO(msf): depending on whether or not we are in multiselect mode, choose instead:
|
|
||||||
<color android:color="?android:attr/colorControlActivated" />
|
|
||||||
-->
|
|
||||||
</item>
|
</item>
|
||||||
</selector>
|
</selector>
|
||||||
</item>
|
</item>
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
type="com.wireguard.android.fragment.TunnelListFragment" />
|
type="com.wireguard.android.fragment.TunnelListFragment" />
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
<RelativeLayout
|
<com.wireguard.android.widget.MultiselectableRelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/list_item_background"
|
android:background="@drawable/list_item_background"
|
||||||
@ -51,5 +51,5 @@
|
|||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
app:checked="@{item.state == State.UP}"
|
app:checked="@{item.state == State.UP}"
|
||||||
app:onBeforeCheckedChanged="@{fragment::setTunnelState}" />
|
app:onBeforeCheckedChanged="@{fragment::setTunnelState}" />
|
||||||
</RelativeLayout>
|
</com.wireguard.android.widget.MultiselectableRelativeLayout>
|
||||||
</layout>
|
</layout>
|
||||||
|
6
app/src/main/res/values/attrs.xml
Normal file
6
app/src/main/res/values/attrs.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<declare-styleable name="Multiselected">
|
||||||
|
<attr name="state_multiselected" format="boolean"/>
|
||||||
|
</declare-styleable>
|
||||||
|
</resources>
|
Loading…
Reference in New Issue
Block a user