mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-24 15:56:07 +00:00
Improve usability of drag-and-drop feature
This commit is contained in:
parent
c73c29d2ec
commit
5886462d2c
8 changed files with 177 additions and 43 deletions
|
@ -43,7 +43,7 @@ public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
|
|||
|
||||
int position = viewHolder.getAdapterPosition();
|
||||
EntryAdapter adapter = (EntryAdapter)recyclerView.getAdapter();
|
||||
if (adapter.getEntryAt(position) != _selectedEntry)
|
||||
if (adapter.getEntryAt(position) != _selectedEntry || !isLongPressDragEnabled())
|
||||
{
|
||||
dragFlags = 0;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.beemdevelopment.aegis.ui.views;
|
|||
|
||||
import android.os.Handler;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
|
@ -49,6 +50,7 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
|||
|
||||
// keeps track of the viewholders that are currently bound
|
||||
private List<EntryHolder> _holders;
|
||||
private EntryHolder _dragHandleHolder; // holder with enabled drag handle
|
||||
|
||||
public EntryAdapter(EntryListView view) {
|
||||
_entries = new ArrayList<>();
|
||||
|
@ -386,7 +388,29 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
|||
holder.setFocusedAndAnimate(true);
|
||||
}
|
||||
|
||||
return _view.onLongEntryClick(_shownEntries.get(position));
|
||||
boolean returnVal = _view.onLongEntryClick(_shownEntries.get(position));
|
||||
|
||||
boolean dragEnabled = _selectedEntries.size() == 0
|
||||
|| _selectedEntries.size() == 1 && _selectedEntries.get(0) == holder.getEntry();
|
||||
if (dragEnabled && isDragAndDropAllowed()) {
|
||||
_view.startDrag(_dragHandleHolder);
|
||||
}
|
||||
|
||||
return returnVal;
|
||||
}
|
||||
});
|
||||
holder.itemView.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
// Start drag if this is the only item selected
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_MOVE
|
||||
&& _selectedEntries.size() == 1
|
||||
&& _selectedEntries.get(0) == holder.getEntry()
|
||||
&& isDragAndDropAllowed()) {
|
||||
_view.startDrag(_dragHandleHolder);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
holder.setOnRefreshClickListener(new View.OnClickListener() {
|
||||
|
@ -508,8 +532,33 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
|||
_focusedEntry = null;
|
||||
}
|
||||
|
||||
private void updateDraggableStatus() {
|
||||
if (!isDragAndDropAllowed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_selectedEntries.size() == 1 && _dragHandleHolder == null) {
|
||||
// Find and enable dragging for the single selected EntryHolder
|
||||
// Not nice but this is the best method I could find
|
||||
for (int i = 0; i < _holders.size(); i++) {
|
||||
if (_holders.get(i).getEntry() == _selectedEntries.get(0)) {
|
||||
_dragHandleHolder = _holders.get(i);
|
||||
_dragHandleHolder.setShowDragHandle(true);
|
||||
_view.setSelectedEntry(_selectedEntries.get(0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (_dragHandleHolder != null) {
|
||||
// Disable dragging if necessary when more/less than 1 selected entry
|
||||
_dragHandleHolder.setShowDragHandle(false);
|
||||
_dragHandleHolder = null;
|
||||
_view.setSelectedEntry(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeSelectedEntry(VaultEntry entry) {
|
||||
_selectedEntries.remove(entry);
|
||||
updateDraggableStatus();
|
||||
}
|
||||
|
||||
public void addSelectedEntry(VaultEntry entry) {
|
||||
|
@ -518,6 +567,7 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
|||
}
|
||||
|
||||
_selectedEntries.add(entry);
|
||||
updateDraggableStatus();
|
||||
}
|
||||
|
||||
public void deselectAllEntries() {
|
||||
|
@ -531,6 +581,8 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
|||
}
|
||||
|
||||
_selectedEntries.clear();
|
||||
|
||||
updateDraggableStatus();
|
||||
}
|
||||
|
||||
public boolean isDragAndDropAllowed() {
|
||||
|
|
|
@ -39,6 +39,7 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
|||
private VaultEntry _entry;
|
||||
private ImageView _buttonRefresh;
|
||||
private RelativeLayout _description;
|
||||
private ImageView _dragHandle;
|
||||
|
||||
private final ImageView _selected;
|
||||
private final Handler _selectedHandler;
|
||||
|
@ -69,6 +70,8 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
|||
_profileDrawable = view.findViewById(R.id.ivTextDrawable);
|
||||
_buttonRefresh = view.findViewById(R.id.buttonRefresh);
|
||||
_selected = view.findViewById(R.id.ivSelected);
|
||||
_dragHandle = view.findViewById(R.id.drag_handle);
|
||||
|
||||
_selectedHandler = new Handler();
|
||||
_animationHandler = new Handler();
|
||||
|
||||
|
@ -158,6 +161,14 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
|||
_buttonRefresh.setOnClickListener(listener);
|
||||
}
|
||||
|
||||
public void setShowDragHandle(boolean showDragHandle) {
|
||||
if (showDragHandle) {
|
||||
_dragHandle.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
_dragHandle.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setShowProgress(boolean showProgress) {
|
||||
if (_entry.getInfo() instanceof HotpInfo) {
|
||||
showProgress = false;
|
||||
|
|
|
@ -42,6 +42,7 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
|||
private EntryAdapter _adapter;
|
||||
private Listener _listener;
|
||||
private SimpleItemTouchHelperCallback _touchCallback;
|
||||
private ItemTouchHelper _touchHelper;
|
||||
|
||||
private RecyclerView _recyclerView;
|
||||
private RecyclerView.ItemDecoration _dividerDecoration;
|
||||
|
@ -90,8 +91,8 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
|||
LinearLayoutManager layoutManager = new LinearLayoutManager(view.getContext());
|
||||
_recyclerView.setLayoutManager(layoutManager);
|
||||
_touchCallback = new SimpleItemTouchHelperCallback(_adapter);
|
||||
ItemTouchHelper touchHelper = new ItemTouchHelper(_touchCallback);
|
||||
touchHelper.attachToRecyclerView(_recyclerView);
|
||||
_touchHelper = new ItemTouchHelper(_touchCallback);
|
||||
_touchHelper.attachToRecyclerView(_recyclerView);
|
||||
_recyclerView.setAdapter(_adapter);
|
||||
|
||||
int resId = R.anim.layout_animation_fall_down;
|
||||
|
@ -167,12 +168,20 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
|||
_touchCallback.setIsLongPressDragEnabled(_adapter.isDragAndDropAllowed());
|
||||
}
|
||||
|
||||
public void setSelectedEntry(VaultEntry entry) {
|
||||
_touchCallback.setSelectedEntry(entry);
|
||||
}
|
||||
|
||||
public void setViewMode(ViewMode mode) {
|
||||
_viewMode = mode;
|
||||
updateDividerDecoration();
|
||||
_adapter.setViewMode(_viewMode);
|
||||
}
|
||||
|
||||
public void startDrag(RecyclerView.ViewHolder viewHolder) {
|
||||
_touchHelper.startDrag(viewHolder);
|
||||
}
|
||||
|
||||
public void refresh(boolean hard) {
|
||||
if (_showProgress) {
|
||||
_progressBar.restart();
|
||||
|
|
5
app/src/main/res/drawable/ic_baseline_menu_black_32.xml
Normal file
5
app/src/main/res/drawable/ic_baseline_menu_black_32.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="32dp" android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z"/>
|
||||
</vector>
|
|
@ -129,20 +129,39 @@
|
|||
android:textStyle="normal|bold"/>
|
||||
|
||||
</RelativeLayout>
|
||||
<ImageView
|
||||
android:id="@+id/buttonRefresh"
|
||||
android:visibility="gone"
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:padding="8dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:src="@drawable/ic_refresh_black_24dp"
|
||||
android:tint="?attr/iconColorPrimary"
|
||||
android:background="?android:attr/selectableItemBackground" />
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/buttonRefresh"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:padding="8dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:src="@drawable/ic_refresh_black_24dp"
|
||||
android:tint="?attr/iconColorPrimary"
|
||||
android:background="?android:attr/selectableItemBackground" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/drag_handle"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="-12dp"
|
||||
android:visibility="invisible"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/ic_baseline_menu_black_32" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
@ -128,20 +128,39 @@
|
|||
android:textStyle="normal|bold"/>
|
||||
|
||||
</RelativeLayout>
|
||||
<ImageView
|
||||
android:id="@+id/buttonRefresh"
|
||||
android:visibility="gone"
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:padding="8dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:src="@drawable/ic_refresh_black_24dp"
|
||||
android:tint="?attr/iconColorPrimary"
|
||||
android:background="?android:attr/selectableItemBackground" />
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/buttonRefresh"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="0dp"
|
||||
android:padding="8dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:src="@drawable/ic_refresh_black_24dp"
|
||||
android:tint="?attr/iconColorPrimary"
|
||||
android:background="?android:attr/selectableItemBackground" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/drag_handle"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="-12dp"
|
||||
android:visibility="invisible"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/ic_baseline_menu_black_32" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
@ -127,20 +127,39 @@
|
|||
android:textStyle="normal|bold"/>
|
||||
|
||||
</RelativeLayout>
|
||||
<ImageView
|
||||
android:id="@+id/buttonRefresh"
|
||||
android:visibility="gone"
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:padding="8dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:src="@drawable/ic_refresh_black_24dp"
|
||||
android:tint="?attr/iconColorPrimary"
|
||||
android:background="?android:attr/selectableItemBackground" />
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/buttonRefresh"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="0dp"
|
||||
android:padding="8dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:src="@drawable/ic_refresh_black_24dp"
|
||||
android:tint="?attr/iconColorPrimary"
|
||||
android:background="?android:attr/selectableItemBackground" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/drag_handle"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="-12dp"
|
||||
android:visibility="invisible"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/ic_baseline_menu_black_32" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
|
Loading…
Add table
Reference in a new issue