Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/stefan-niedermann/nextcloud-notes.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Niedermann <info@niedermann.it>2020-10-19 12:19:43 +0300
committerStefan Niedermann <info@niedermann.it>2020-10-19 12:19:43 +0300
commitbc1f4040dad728b5620fa50b6248e0cc45a27797 (patch)
tree67337a9c984bfa77c6d15600a99b59c9ffdbfde3 /app/src/main/java
parent2d50087fb88d9dfe74a8d2234588bd73703600b6 (diff)
recyclerview-selection
Diffstat (limited to 'app/src/main/java')
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java2
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java2
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java78
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java10
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java35
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/items/ItemAdapter.java115
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java10
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolder.java5
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolderOnlyTitle.java6
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithExcerpt.java5
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithoutExcerpt.java5
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java2
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/dao/NoteDao.java4
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java2
14 files changed, 175 insertions, 106 deletions
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java
index 0924aacf..6359b4b4 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java
@@ -108,7 +108,7 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego
SingleAccountHelper.setCurrentAccount(requireActivity().getApplicationContext(), localAccount.getAccountName());
}
isNew = false;
- note = originalNote = db.getNoteDao().getFullNoteWithCategory(localAccount.getId(), id);
+ note = originalNote = db.getNoteDao().getFullNoteWithCategory(id);
} else {
NoteWithCategory cloudNote = (NoteWithCategory) requireArguments().getSerializable(PARAM_NEWNOTE);
String content = requireArguments().getString(PARAM_CONTENT);
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java
index 5c6fbbef..5758afe8 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java
@@ -213,7 +213,7 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O
TextProcessorChain chain = defaultTextProcessorChain(note.getNote());
Account account = db.getAccountDao().getLocalAccountByAccountName(SingleAccountHelper.getCurrentSingleSignOnAccount(requireContext()).name);
db.getNoteServerSyncHelper().addCallbackPull(account, () -> {
- note = db.getNoteDao().getFullNoteWithCategory(note.getAccountId(), note.getId());
+ note = db.getNoteDao().getFullNoteWithCategory(note.getId());
changedText = note.getContent();
binding.singleNoteContent.setText(parseCompat(markdownProcessor, chain.apply(note.getContent())));
binding.swiperefreshlayout.setRefreshing(false);
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java
index ecd66689..a0752dc0 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java
@@ -27,6 +27,10 @@ import androidx.core.view.ViewCompat;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
+import androidx.recyclerview.selection.SelectionPredicates;
+import androidx.recyclerview.selection.SelectionTracker;
+import androidx.recyclerview.selection.SelectionTracker.SelectionObserver;
+import androidx.recyclerview.selection.StorageStrategy;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
@@ -44,6 +48,7 @@ import com.nextcloud.android.sso.exceptions.TokenMismatchException;
import com.nextcloud.android.sso.helper.SingleAccountHelper;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import it.niedermann.owncloud.notes.ImportAccountActivity;
import it.niedermann.owncloud.notes.LockedActivity;
@@ -111,6 +116,8 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A
private NavigationAdapter adapterCategories;
private MenuAdapter menuAdapter;
+ private SelectionTracker<Long> tracker;
+
protected DrawerLayoutBinding binding;
protected ActivityNotesListViewBinding activityBinding;
protected FloatingActionButton fabCreate;
@@ -206,10 +213,10 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A
});
});
mainViewModel.getNotesListLiveData().observe(this, notes -> {
- adapter.clearSelection(listView);
- if (mActionMode != null) {
- mActionMode.finish();
- }
+// adapter.clearSelection(listView);
+// if (mActionMode != null) {
+// mActionMode.finish();
+// }
adapter.setItemList(notes);
binding.activityNotesListView.progressCircular.setVisibility(GONE);
binding.activityNotesListView.emptyContentView.getRoot().setVisibility(notes.size() > 0 ? GONE : VISIBLE);
@@ -386,6 +393,22 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A
};
syncLiveData.observe(this, syncObserver);
});
+
+ tracker = new SelectionTracker.Builder<>(
+ "selection-1",
+ listView,
+ new ItemAdapter.ItemIdKeyProvider(listView),
+ new ItemAdapter.ItemLookup(listView),
+ StorageStrategy.createLongStorage()
+ ).withSelectionPredicate(SelectionPredicates.createSelectAnything()).build();
+ adapter.setTracker(tracker);
+ tracker.addObserver(new SelectionObserver<Long>() {
+ @Override
+ public void onSelectionChanged() {
+ super.onSelectionChanged();
+ }
+ });
+
}
private void setupNavigationList() {
@@ -578,21 +601,8 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A
@Override
public void onNoteClick(int position, View v) {
- boolean hasCheckedItems = adapter.getSelected().size() > 0;
- if (hasCheckedItems) {
- if (!adapter.select(position)) {
- v.setSelected(false);
- adapter.deselect(position);
- } else {
- v.setSelected(true);
- }
- int size = adapter.getSelected().size();
- if (size > 0) {
- mActionMode.setTitle(getResources().getQuantityString(R.plurals.ab_selected, size, size));
- } else {
- mActionMode.finish();
- }
- } else {
+ boolean hasCheckedItems = tracker.getSelection().size() > 0;
+ if (!hasCheckedItems) {
NoteWithCategory note = (NoteWithCategory) adapter.getItem(position);
Intent intent = new Intent(getApplicationContext(), EditNoteActivity.class);
intent.putExtra(EditNoteActivity.PARAM_NOTE_ID, note.getId());
@@ -608,14 +618,13 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A
@Override
public boolean onNoteLongClick(int position, View v) {
- boolean selected = adapter.select(position);
- if (selected) {
- v.setSelected(true);
- mActionMode = startSupportActionMode(new MultiSelectedActionModeCallback(this, coordinatorLayout, mainViewModel, this, canMoveNoteToAnotherAccounts, adapter, listView, getSupportFragmentManager(), activityBinding.searchView));
- final int checkedItemCount = adapter.getSelected().size();
- mActionMode.setTitle(getResources().getQuantityString(R.plurals.ab_selected, checkedItemCount, checkedItemCount));
- }
- return selected;
+// int selected = tracker.getSelection().size();
+// if (selected > 0) {
+// v.setSelected(true);
+// mActionMode = startSupportActionMode(new MultiSelectedActionModeCallback(this, coordinatorLayout, mainViewModel, this, canMoveNoteToAnotherAccounts, tracker, listView, getSupportFragmentManager(), activityBinding.searchView));
+// mActionMode.setTitle(getResources().getQuantityString(R.plurals.ab_selected, selected, selected));
+// }
+ return true;
}
@Override
@@ -655,20 +664,17 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A
@Override
public void onAccountPicked(@NonNull Account account) {
- for (Integer i : adapter.getSelected()) {
- final LiveData<NoteWithCategory> moveLiveData = mainViewModel.moveNoteToAnotherAccount(account, (NoteWithCategory) adapter.getItem(i));
- moveLiveData.observe(this, (v) -> moveLiveData.removeObservers(this));
+ for(Long noteId : tracker.getSelection()) {
+ new Thread(() -> {
+ final LiveData<NoteWithCategory> moveLiveData = mainViewModel.moveNoteToAnotherAccount(account, noteId);
+ moveLiveData.observe(this, (v) -> moveLiveData.removeObservers(this));
+ }).start();
}
}
@Override
public void onCategoryChosen(String category) {
- final LiveData<Void> categoryLiveData = mainViewModel.setCategory(
- adapter.getSelected()
- .stream()
- .map(item -> ((NoteWithCategory) adapter.getItem(item)).getId())
- .collect(Collectors.toList())
- , category);
+ final LiveData<Void> categoryLiveData = mainViewModel.setCategory(tracker.getSelection(), category);
categoryLiveData.observe(this, (next) -> categoryLiveData.removeObservers(this));
}
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java b/app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java
index 9515df1d..b5e98735 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java
@@ -427,7 +427,7 @@ public class MainViewModel extends AndroidViewModel {
return db.getAccountDao().getAccounts();
}
- public LiveData<Void> setCategory(Collection<Long> noteIds, @NonNull String category) {
+ public LiveData<Void> setCategory(Iterable<Long> noteIds, @NonNull String category) {
return switchMap(getCurrentAccount(), currentAccount -> {
if (currentAccount == null) {
return new MutableLiveData<>(null);
@@ -441,8 +441,8 @@ public class MainViewModel extends AndroidViewModel {
});
}
- public LiveData<NoteWithCategory> moveNoteToAnotherAccount(Account account, NoteWithCategory note) {
- return db.moveNoteToAnotherAccount(account, note);
+ public LiveData<NoteWithCategory> moveNoteToAnotherAccount(Account account, Long noteId) {
+ return db.moveNoteToAnotherAccount(account, db.getNoteDao().getFullNoteWithCategory(noteId));
}
@WorkerThread
@@ -506,7 +506,7 @@ public class MainViewModel extends AndroidViewModel {
new Thread(() -> notes.postValue(
ids
.stream()
- .map(id -> db.getNoteDao().getFullNoteWithCategory(currentAccount.getId(), id))
+ .map(id -> db.getNoteDao().getFullNoteWithCategory(id))
.collect(Collectors.toList())
)).start();
return notes;
@@ -551,7 +551,7 @@ public class MainViewModel extends AndroidViewModel {
new Thread(() -> {
final StringBuilder noteContents = new StringBuilder();
for (Long noteId : noteIds) {
- final NoteWithCategory fullNote = db.getNoteDao().getFullNoteWithCategory(currentAccount.getId(), noteId);
+ final NoteWithCategory fullNote = db.getNoteDao().getFullNoteWithCategory(noteId);
final String tempFullNote = fullNote.getContent();
if (!TextUtils.isEmpty(tempFullNote)) {
if (noteContents.length() > 0) {
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java b/app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java
index b1afad4c..0734f5b6 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/main/MultiSelectedActionModeCallback.java
@@ -16,6 +16,7 @@ import androidx.core.graphics.drawable.DrawableCompat;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
+import androidx.recyclerview.selection.SelectionTracker;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.snackbar.Snackbar;
@@ -23,6 +24,7 @@ import com.google.android.material.snackbar.Snackbar;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.accountpicker.AccountPickerDialogFragment;
@@ -46,19 +48,19 @@ public class MultiSelectedActionModeCallback implements Callback {
@NonNull
private final LifecycleOwner lifecycleOwner;
private final boolean canMoveNoteToAnotherAccounts;
- private final ItemAdapter adapter;
+ private final SelectionTracker<Long> tracker;
private final RecyclerView recyclerView;
private final FragmentManager fragmentManager;
private final SearchView searchView;
public MultiSelectedActionModeCallback(
- @NonNull Context context, @NonNull View view, @NonNull MainViewModel mainViewModel, @NonNull LifecycleOwner lifecycleOwner, boolean canMoveNoteToAnotherAccounts, ItemAdapter adapter, RecyclerView recyclerView, FragmentManager fragmentManager, SearchView searchView) {
+ @NonNull Context context, @NonNull View view, @NonNull MainViewModel mainViewModel, @NonNull LifecycleOwner lifecycleOwner, boolean canMoveNoteToAnotherAccounts, SelectionTracker<Long> tracker, RecyclerView recyclerView, FragmentManager fragmentManager, SearchView searchView) {
this.context = context;
this.view = view;
this.mainViewModel = mainViewModel;
this.lifecycleOwner = lifecycleOwner;
this.canMoveNoteToAnotherAccounts = canMoveNoteToAnotherAccounts;
- this.adapter = adapter;
+ this.tracker = tracker;
this.recyclerView = recyclerView;
this.fragmentManager = fragmentManager;
this.searchView = searchView;
@@ -98,7 +100,10 @@ public class MultiSelectedActionModeCallback implements Callback {
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int itemId = item.getItemId();
if (itemId == R.id.menu_delete) {
- final List<Long> selection = adapter.getSelected().stream().map(itemPosition -> ((NoteWithCategory) adapter.getItem(itemPosition)).getId()).collect(Collectors.toList());
+ final List<Long> selection = new ArrayList<>(tracker.getSelection().size());
+ for(Long sel : tracker.getSelection()) {
+ selection.add(sel);
+ }
final LiveData<List<NoteWithCategory>> fullNotes$ = mainViewModel.getFullNotesWithCategory(selection);
fullNotes$.observe(lifecycleOwner, (fullNotes) -> {
fullNotes$.removeObservers(lifecycleOwner);
@@ -133,15 +138,17 @@ public class MultiSelectedActionModeCallback implements Callback {
});
return true;
} else if (itemId == R.id.menu_share) {
- final String subject = (adapter.getSelected().size() == 1)
- ? ((NoteWithCategory) adapter.getItem(adapter.getSelected().get(0))).getTitle()
- : context.getResources().getQuantityString(R.plurals.share_multiple, adapter.getSelected().size(), adapter.getSelected().size());
+ final List<Long> selection = new ArrayList<>(tracker.getSelection().size());
+ for(Long sel : tracker.getSelection()) {
+ selection.add(sel);
+ }
+ // FIXME
+ final String subject = context.getResources().getQuantityString(R.plurals.share_multiple, selection.size(), selection.size());
+// final String subject = (selection.size() == 1)
+// ? ((NoteWithCategory) adapter.getItem(adapter.getSelected().get(0))).getTitle()
+// : context.getResources().getQuantityString(R.plurals.share_multiple, adapter.getSelected().size(), adapter.getSelected().size());
- final LiveData<String> contentCollector = mainViewModel.collectNoteContents(
- adapter.getSelected()
- .stream()
- .map(itemPosition -> ((NoteWithCategory) adapter.getItem(itemPosition)).getId())
- .collect(Collectors.toList()));
+ final LiveData<String> contentCollector = mainViewModel.collectNoteContents(selection);
contentCollector.observe(lifecycleOwner, (next) -> {
contentCollector.removeObservers(lifecycleOwner);
ShareUtil.openShareDialog(context, subject, next);
@@ -163,7 +170,7 @@ public class MultiSelectedActionModeCallback implements Callback {
@Override
public void onDestroyActionMode(ActionMode mode) {
- adapter.clearSelection(recyclerView);
- adapter.notifyDataSetChanged();
+// adapter.clearSelection(recyclerView);
+// adapter.notifyDataSetChanged();
}
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/ItemAdapter.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/ItemAdapter.java
index 39f640a9..81a71ed0 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/ItemAdapter.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/ItemAdapter.java
@@ -4,15 +4,20 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.text.TextUtils;
-import android.util.Log;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.ColorInt;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.Px;
import androidx.preference.PreferenceManager;
+import androidx.recyclerview.selection.ItemDetailsLookup;
+import androidx.recyclerview.selection.ItemKeyProvider;
+import androidx.recyclerview.selection.SelectionTracker;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
@@ -35,6 +40,7 @@ import it.niedermann.owncloud.notes.persistence.entity.NoteWithCategory;
import it.niedermann.owncloud.notes.shared.model.Item;
import it.niedermann.owncloud.notes.shared.model.NoteClickListener;
+import static androidx.recyclerview.widget.RecyclerView.NO_POSITION;
import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences;
public class ItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Branded {
@@ -51,7 +57,8 @@ public class ItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> i
private List<Item> itemList = new ArrayList<>();
private boolean showCategory = true;
private CharSequence searchQuery;
- private final List<Integer> selected = new ArrayList<>();
+ private SelectionTracker<Long> tracker = null;
+ // private final List<Integer> selected = new ArrayList<>();
@Px
private final float fontSize;
private final boolean monospace;
@@ -68,20 +75,17 @@ public class ItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> i
final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
this.fontSize = getFontSizeFromPreferences(context, sp);
this.monospace = sp.getBoolean(context.getString(R.string.pref_key_font), false);
- // FIXME see getItemId()
- // setHasStableIds(true);
+ setHasStableIds(true);
}
- /*
- FIXME this causes {@link it.niedermann.owncloud.notes.noteslist.items.list.NotesListViewItemTouchHelper} to not call clearView anymore → After marking a note as favorite, it stays yellow.
- @Override
- public long getItemId(int position) {
- return getItemViewType(position) == TYPE_SECTION
- ? ((SectionItem) getItem(position)).getTitle().hashCode() * -1
- : ((NoteEntity) getItem(position)).getId();
- }
- */
+ // FIXME this causes {@link it.niedermann.owncloud.notes.noteslist.items.list.NotesListViewItemTouchHelper} to not call clearView anymore → After marking a note as favorite, it stays yellow.
+ @Override
+ public long getItemId(int position) {
+ return getItemViewType(position) == TYPE_SECTION
+ ? ((SectionItem) getItem(position)).getTitle().hashCode() * -1
+ : ((NoteWithCategory) getItem(position)).getId();
+ }
/**
* Updates the item list and notifies respective view to update.
@@ -134,6 +138,16 @@ public class ItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> i
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
+ boolean isSelected = false;
+ if(tracker != null) {
+ Long itemId = getItemId(position);
+ if(tracker.isSelected(itemId)) {
+ tracker.select(itemId);
+ isSelected = true;
+ } else {
+ tracker.deselect(itemId);
+ }
+ }
switch (getItemViewType(position)) {
case TYPE_SECTION: {
((SectionViewHolder) holder).bind((SectionItem) itemList.get(position));
@@ -142,42 +156,73 @@ public class ItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> i
case TYPE_NOTE_WITH_EXCERPT:
case TYPE_NOTE_WITHOUT_EXCERPT:
case TYPE_NOTE_ONLY_TITLE: {
- ((NoteViewHolder) holder).bind((NoteWithCategory) itemList.get(position), showCategory, mainColor, textColor, searchQuery);
+ ((NoteViewHolder) holder).bind(new ItemDetailsLookup.ItemDetails<Long>() {
+ @Override
+ public int getPosition() {
+ return position;
+ }
+
+ @Override
+ public Long getSelectionKey() {
+ return getItemId(position);
+ }
+ }, isSelected, (NoteWithCategory) itemList.get(position), showCategory, mainColor, textColor, searchQuery);
break;
}
}
}
- public boolean select(Integer position) {
- return !selected.contains(position) && selected.add(position);
+ // --------------------------------------------------------------------------------------------
+
+
+ public void setTracker(SelectionTracker<Long> tracker) {
+ this.tracker = tracker;
}
- public void clearSelection(@NonNull RecyclerView recyclerView) {
- for (Integer i : getSelected()) {
- RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(i);
- if (viewHolder != null) {
- viewHolder.itemView.setSelected(false);
- } else {
- Log.w(TAG, "Could not found " + RecyclerView.ViewHolder.class.getSimpleName() + " to remove selection");
+ public static class ItemIdKeyProvider extends ItemKeyProvider<Long> {
+ private final RecyclerView recyclerView;
+
+ public ItemIdKeyProvider(RecyclerView recyclerView) {
+ super(SCOPE_MAPPED);
+ this.recyclerView = recyclerView;
+ }
+
+ @Nullable
+ @Override
+ public Long getKey(int position) {
+ final RecyclerView.Adapter<?> adapter = recyclerView.getAdapter();
+ if (adapter == null) {
+ throw new IllegalStateException("RecyclerView adapter is not set!");
}
+ return adapter.getItemId(position);
}
- selected.clear();
- }
- @NonNull
- public List<Integer> getSelected() {
- return selected;
+ @Override
+ public int getPosition(@NonNull Long key) {
+ final RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForItemId(key);
+ return viewHolder == null ? NO_POSITION : viewHolder.getLayoutPosition();
+ }
}
- public void deselect(Integer position) {
- for (int i = 0; i < selected.size(); i++) {
- if (selected.get(i).equals(position)) {
- //position was selected and removed
- selected.remove(i);
- return;
+ public static class ItemLookup extends ItemDetailsLookup<Long> {
+
+ @NonNull
+ private final RecyclerView rv;
+
+ public ItemLookup(@NonNull RecyclerView recyclerView) {
+ this.rv = recyclerView;
+ }
+
+ @Nullable
+ @Override
+ public ItemDetails<Long> getItemDetails(@NonNull MotionEvent e) {
+ View view = rv.findChildViewUnder(e.getX(), e.getY());
+ if(view != null) {
+ return ((NoteViewHolder) rv.getChildViewHolder(view))
+ .getItemDetails();
}
+ return null;
}
- // position was not selected
}
public Item getItem(int notePosition) {
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java
index 01860919..79b6b7a8 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java
@@ -19,6 +19,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.core.graphics.drawable.DrawableCompat;
+import androidx.recyclerview.selection.ItemDetailsLookup;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.chip.Chip;
@@ -42,6 +43,7 @@ import static it.niedermann.owncloud.notes.shared.util.ColorUtil.isColorDark;
public abstract class NoteViewHolder extends RecyclerView.ViewHolder {
@NonNull
private final NoteClickListener noteClickListener;
+ private ItemDetailsLookup.ItemDetails<Long> itemDetails;
public NoteViewHolder(@NonNull View v, @NonNull NoteClickListener noteClickListener) {
super(v);
@@ -50,7 +52,9 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder {
}
@CallSuper
- public void bind(@NonNull NoteWithCategory note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) {
+ public void bind(@NonNull ItemDetailsLookup.ItemDetails<Long> itemDetails, boolean isSelected, @NonNull NoteWithCategory note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) {
+ this.itemDetails = itemDetails;
+ itemView.setSelected(isSelected);
itemView.setOnClickListener((view) -> noteClickListener.onNoteClick(getAdapterPosition(), view));
itemView.setOnLongClickListener((view) -> noteClickListener.onNoteLongClick(getAdapterPosition(), view));
}
@@ -137,4 +141,8 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder {
@Nullable
public abstract View getNoteSwipeable();
+
+ public ItemDetailsLookup.ItemDetails<Long> getItemDetails() {
+ return itemDetails;
+ }
} \ No newline at end of file
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolder.java
index f118de43..6f73e8e4 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolder.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolder.java
@@ -9,6 +9,7 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Px;
+import androidx.recyclerview.selection.ItemDetailsLookup;
import it.niedermann.owncloud.notes.databinding.ItemNotesListNoteItemGridBinding;
import it.niedermann.owncloud.notes.main.items.NoteViewHolder;
@@ -40,8 +41,8 @@ public class NoteViewGridHolder extends NoteViewHolder {
throw new UnsupportedOperationException(NoteViewGridHolder.class.getSimpleName() + " does not support swiping");
}
- public void bind(@NonNull NoteWithCategory noteWithCategory, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) {
- super.bind(noteWithCategory, showCategory, mainColor, textColor, searchQuery);
+ public void bind(@NonNull ItemDetailsLookup.ItemDetails<Long> itemDetails, boolean isSelected, @NonNull NoteWithCategory noteWithCategory, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) {
+ super.bind(itemDetails, isSelected, noteWithCategory, showCategory, mainColor, textColor, searchQuery);
Note note = noteWithCategory.getNote();
@NonNull final Context context = itemView.getContext();
bindCategory(context, binding.noteCategory, showCategory, noteWithCategory.getCategory(), mainColor);
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolderOnlyTitle.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolderOnlyTitle.java
index 11468ba4..b0292d3f 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolderOnlyTitle.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolderOnlyTitle.java
@@ -8,10 +8,10 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Px;
+import androidx.recyclerview.selection.ItemDetailsLookup;
import it.niedermann.owncloud.notes.databinding.ItemNotesListNoteItemGridOnlyTitleBinding;
import it.niedermann.owncloud.notes.main.items.NoteViewHolder;
-import it.niedermann.owncloud.notes.persistence.entity.Note;
import it.niedermann.owncloud.notes.persistence.entity.NoteWithCategory;
import it.niedermann.owncloud.notes.shared.model.NoteClickListener;
@@ -33,8 +33,8 @@ public class NoteViewGridHolderOnlyTitle extends NoteViewHolder {
throw new UnsupportedOperationException(NoteViewGridHolderOnlyTitle.class.getSimpleName() + " does not support swiping");
}
- public void bind(@NonNull NoteWithCategory note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) {
- super.bind(note, showCategory, mainColor, textColor, searchQuery);
+ public void bind(@NonNull ItemDetailsLookup.ItemDetails<Long> itemDetails, boolean isSelected, @NonNull NoteWithCategory note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) {
+ super.bind(itemDetails, isSelected, note, showCategory, mainColor, textColor, searchQuery);
@NonNull final Context context = itemView.getContext();
bindStatus(binding.noteStatus, note.getStatus(), mainColor);
bindFavorite(binding.noteFavorite, note.getFavorite());
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithExcerpt.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithExcerpt.java
index 726267a1..80379ada 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithExcerpt.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithExcerpt.java
@@ -5,6 +5,7 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.recyclerview.selection.ItemDetailsLookup;
import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.databinding.ItemNotesListNoteItemWithExcerptBinding;
@@ -29,8 +30,8 @@ public class NoteViewHolderWithExcerpt extends NoteViewHolder {
binding.noteSwipeFrame.setBackgroundResource(left ? R.color.bg_warning : R.color.bg_attention);
}
- public void bind(@NonNull NoteWithCategory noteWithCategory, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) {
- super.bind(noteWithCategory, showCategory, mainColor, textColor, searchQuery);
+ public void bind(@NonNull ItemDetailsLookup.ItemDetails<Long> itemDetails, boolean isSelected, @NonNull NoteWithCategory noteWithCategory, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) {
+ super.bind(itemDetails, isSelected, noteWithCategory, showCategory, mainColor, textColor, searchQuery);
Note note = noteWithCategory.getNote();
@NonNull final Context context = itemView.getContext();
binding.noteSwipeable.setAlpha(DBStatus.LOCAL_DELETED.equals(note.getStatus()) ? 0.5f : 1.0f);
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithoutExcerpt.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithoutExcerpt.java
index 165329ac..7435ceec 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithoutExcerpt.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithoutExcerpt.java
@@ -5,6 +5,7 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.recyclerview.selection.ItemDetailsLookup;
import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.databinding.ItemNotesListNoteItemWithoutExcerptBinding;
@@ -29,8 +30,8 @@ public class NoteViewHolderWithoutExcerpt extends NoteViewHolder {
binding.noteSwipeFrame.setBackgroundResource(left ? R.color.bg_warning : R.color.bg_attention);
}
- public void bind(@NonNull NoteWithCategory noteWithCategory, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) {
- super.bind(noteWithCategory, showCategory, mainColor, textColor, searchQuery);
+ public void bind(@NonNull ItemDetailsLookup.ItemDetails<Long> itemDetails, boolean isSelected, @NonNull NoteWithCategory noteWithCategory, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) {
+ super.bind(itemDetails, isSelected, noteWithCategory, showCategory, mainColor, textColor, searchQuery);
Note note = noteWithCategory.getNote();
@NonNull final Context context = itemView.getContext();
binding.noteSwipeable.setAlpha(DBStatus.LOCAL_DELETED.equals(note.getStatus()) ? 0.5f : 1.0f);
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java
index 3fa1c652..c0a32fd4 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java
@@ -202,7 +202,7 @@ public abstract class NotesDatabase extends RoomDatabase {
entity.setFavorite(note.getFavorite());
entity.setCategoryId(getOrCreateCategoryIdByTitle(accountId, note.getCategory()));
entity.setETag(note.getETag());
- return getNoteDao().getFullNoteWithCategory(accountId, getNoteDao().addNote(entity));
+ return getNoteDao().getFullNoteWithCategory(getNoteDao().addNote(entity));
}
@AnyThread
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/dao/NoteDao.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/dao/NoteDao.java
index 58c3d567..54e57a41 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/dao/NoteDao.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/dao/NoteDao.java
@@ -73,8 +73,8 @@ public interface NoteDao {
@Query("UPDATE NOTE SET scrollY = :scrollY WHERE id = :id")
void updateScrollY(long id, int scrollY);
- @Query("SELECT NOTE.*, CATEGORY.title as 'category' FROM NOTE INNER JOIN CATEGORY ON categoryId = CATEGORY.id WHERE NOTE.id = :id AND NOTE.accountId = :accountId AND status != :accountId")
- NoteWithCategory getFullNoteWithCategory(long accountId, long id);
+ @Query("SELECT NOTE.*, CATEGORY.title as 'category' FROM NOTE INNER JOIN CATEGORY ON categoryId = CATEGORY.id WHERE NOTE.id = :id")
+ NoteWithCategory getFullNoteWithCategory(long id);
@Query("SELECT NOTE.*, CATEGORY.title as 'category' FROM NOTE INNER JOIN CATEGORY ON categoryId = CATEGORY.id WHERE NOTE.id = :id AND NOTE.accountId = :accountId AND status != :accountId")
LiveData<NoteWithCategory> getNoteWithCategoryLiveData(long accountId, long id);
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java
index 5206409e..cba7b691 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java
@@ -61,7 +61,7 @@ public class SingleNoteWidgetFactory implements RemoteViewsService.RemoteViewsFa
if (data != null) {
final long noteId = data.getNoteId();
Log.v(TAG, "Fetch note with id " + noteId);
- note = db.getNoteDao().getFullNoteWithCategory(data.getAccountId(), noteId);
+ note = db.getNoteDao().getFullNoteWithCategory(noteId);
if (note == null) {
Log.e(TAG, "Error: note not found");