Anki-android: Select multiple cards in the card browser

Created on 28 Jul 2015  路  28Comments  路  Source: ankidroid/Anki-Android

Originally reported on Google Code with ID 1437

It would be useful I think if you were able to select multiple cards in the card browser
so that you could (un)suspend, or delete, or whatever, 100 cards at once, instead of
having to long click on each one which takes a while :)
Maybe when in the card browser, you press the meny key, and in the list that shows
up (Undo, Add note, Change CardBrowser field (-should that have a space in or not??)..
and so on), there could be an item that is multi select, and then you can tap multiple
cards and they stay selected. Maybe long pressing or one of them will trigger the properties
for all of them, or maybe once multiselecting, you would have to press menu again and
select the action from there.

I tried to search if this idea was said before, but I could not find it. Thanks!
!

Reported by woof.addict on 2012-10-20 13:12:08

Accepted Enhancement Help Wanted Priority-High

Most helpful comment

I've implemented everything and made a pull request. Now, mark, suspend, delete and change deck work for multiple selected items (as far as I've tested).

All 28 comments

I am in a similar position.  Only being able to unsuspend one card at a time is an unreasonable
limitation.  The developer-recommended method of progressing through a deck that is
divided into chapters is to suspend the whole thing, then use tags to unsuspend the
the subsequent chapters.  With no way to select multiple cars in the Ankidroid browser,
I am only able to effectively open new chapters from a PC.  The software is only in
beta, but this still seems like a significant oversight, unless there is some strange
technical issue preventing it.  My understanding was that this was a late beta.  Major
features should be implemented by this point, shouldn't they?

Reported by blavigne13 on 2013-01-02 04:28:15

This would be a useful feature; I'm setting priority to high. Developers feel free to
change.

Reported by perceptualchaos2 on 2013-01-09 05:37:29

  • Status changed: Accepted
  • Labels added: Priority-High
  • Labels removed: Priority-Undecided
This "select all" feature seems to be getting requested a lot, for people who want to
select all and suspend for selective study purposes.

Reported by perceptualchaos2 on 2013-01-19 23:18:13

Issue 1577 has been merged into this issue.

Reported by perceptualchaos2 on 2013-01-19 23:19:21

Reply for closed Issue 1577:
=====
> But using expressions like "tag:NNN" or "is:new" seems not working in AnkiDroid Browser.


Are you using version 2.0 of AnkiDroid? These search queries work fine.
=====

Strange thing - "tag:NNN" search did not work (always returned 0 cards) until I tried
to do a simple keyword search. After the first simple search query was completed, "tag:NNN"
expressions start working as expected.

Reported by Yu.I.Kornilov on 2013-01-20 14:18:15

Has anybody found a workaround for this? There's no way I'm individually long-press-tapping
390 cards tto suspend a group of cards. At this rate it'll be quicker to create a new
deck or install and sync desktop Anki from a PC.

Reported by denpashogai on 2014-10-08 19:40:58

Anki Desktop is currently easiest way

Reported by perceptualchaos2 on 2014-10-09 01:09:04

An Ankidroid user in my office today expressed interest in this feature.

I've been looking into this today but the little progress bar that pops up when loading the cards in the card browser keeps restarting unless i scroll to the bottom, in which case it keeps throwing a "java.util.concurrent.CancellationException" exception. It works fine on my actual phone though, is it just an issue with the emulator (API 24)? The latest version in master also does this.

This is my fork:
https://github.com/chickendude/Anki-Android

Long-clicking an item brings up the check boxes, suspending, marking a note, and previewing (a single note) appear to work fine, deleting a note seems to still have some issues that i'm trying to iron out. Also, suspending notes was a bit more complicated than i thought (case R.id.action_suspend_card in onOptionsItemSelected) and is pretty slow. There are also a few strings which should probably be added with plural forms like "Suspend card(s)", "Mark card(s)", etc. and maybe having a preview icon rather than having to access the menu.

I'd be happy to continue working on it if you think it's usable, it's my first time contributing to another project, so not sure what to expect.

Hi sorry for the slow response. Thanks a lot for working on this.

How about just calling setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL) on the ListView? This will highlight the selected item(s) in the ListView, and bring up a special contextual action bar where you can choose which action to take on those items. You can see an example here

The advantage of such an approach is that we don't need to add our own checkboxes to the layout, or manage when they are / aren't shown, etc.

Let me know what you think

Launching a new DeckTask for each card / note that you want to suspend/delete is always going to be very slow as each task will make its own database update. You'll want to instead pass in a list of ids that you want to apply the action to.

Libanki already has the functions suspendCards(), and remNotes() which are optimized for bulk actions, so you'll probably need to change the arguments you pass into the task to use arrays (or alternatively make new tasks to handle these bulk actions).

So for example here you'd want to change this

for (int cardPosition : mCheckedCardPositions) {
    final Card card = getCol().getCard(Long.parseLong(getCards().get(cardPosition).get("id")));
    deleteNote(card);
    DeckTask.launchDeckTask(DeckTask.TASK_TYPE_DISMISS, mDeleteNoteHandler,
            new DeckTask.TaskData(new Object[]{card, Collection.DismissType.DELETE_NOTE}));
}

to move the DeckTask.launchDeckTask() outside the loop

What editor are you using for working on this? It's kinda screwing up all the indentation, shifting things around and mixing spaces with tabs which makes it harder to review. This shouldn't happen if you import the project directly into Android Studio, which I highly recommend.

By the way, I noticed that you're committing directly to the master branch which is generally a bad idea as you'll start getting merge conflicts all over the place. Please have a quick read of the git workflow section of the wiki. Let me know if you have any questions about the code or git!

No worries, and thanks for all the help! I didn't know about that ListView mode, that'd be helpful indeed! I'm working in Android Studio but i generally work with tabs, so that's probably where the issues came up. I'll switch it over to spaces for this project and see if that helps. I'll also switch into a branch, should i delete the fork and restart it all in a new branch?

Deleting isn't necessary, just do
git checkout -b browser-multiselect

and then reset your master to upstream/HEAD

Great, thanks! I think i've got everything back to normal in my master branch and the changes pushed over into the browser-multiselect branch. I'll work on implementing your suggested changes and then i'll get back to you here.

Any news on this? Is anybody still working on this feature?

Hey @timrae, I've been looking at this again, it seems the ListView.CHOICE_MODE_MULTIPLE_MODAL setting as well as ListView.setMultiChoiceModeListener were added in API 11, and the current minimum is 10, which i believe is why i opted for manually setting it up to begin with. Alternatively we could only support multi-selection for API >=11 (probably close to 100% of the userbase anyway). I'm currently taking another look at the DeckTask to move the DeckTask call outside of the loop and only have one single call.

EDIT: Also, while testing this out, it seems like the ProgressBar never disappears if the first or last answer is empty (ie. you only provided a question, no answer). This is the section i'm looking at.

So what would you say is the best way to pass in an array to the DeckTask? The current DeckTask code just accepts a single card, so i thought perhaps of adding a new task type, such as TASK_TYPE_DISMISS_MULTI which would call a new method "doInBackgroundDismissNotes(params)" to pass in an array of ids to the remNotes method, but there doesn't appear to be a method to handle bulk-updating the undo, but that is just an ArrayList, right? I've pushed a first commit to handle deleting multiple notes at once. I haven't updated marking/suspending yet.

the current minimum is 10

The current minimum is 14... Maybe you need to rebase?

The current DeckTask code just accepts a single card, so i thought perhaps of adding a new task type

If you need to add a new task type feel free... Don't worry too much about deep implementation details like that for now, we can go through that during code review.

Any progress on this? I'd look into this if nobody's currently working on it, maybe by working on @chickendude 's fork. I think it would be a really useful feature.

Any progress on this? I'd look into this if nobody's currently working on it, maybe by working on @chickendude 's fork. I think it would be a really useful feature.

I haven't seen anything on this since Tim's comments on Feb 23 but I'd like this too - it is a feature the desktop has that I do use

Okay I made some fixes and will work on it more during the next days hopefully.

I've implemented everything and made a pull request. Now, mark, suspend, delete and change deck work for multiple selected items (as far as I've tested).

@vrublack Nice work! I got a bit side-tracked and seems i missed Tim's comment, thanks for finishing this up! I saw your message last week, just had time now to stop by and see you've already finished! I'll take a look at it this weekend (or earlier if i can find the time) to double-check things are working as planned.

Out now in 2.9alpha24! Thanks so much to @vrublack for his dedication to getting this across the finish line and to @chickendude for getting it started!

Was this page helpful?
0 / 5 - 0 ratings