You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
6.3 KiB
149 lines
6.3 KiB
/* |
|
* Copyright 2010-2018 Eric Kok et al. |
|
* |
|
* Transdroid is free software: you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation, either version 3 of the License, or |
|
* (at your option) any later version. |
|
* |
|
* Transdroid is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>. |
|
*/ |
|
package org.transdroid.core.gui.navigation; |
|
|
|
import org.transdroid.core.gui.navigation.SelectionModificationSpinner.OnModificationActionSelectedListener; |
|
import org.transdroid.daemon.Finishable; |
|
|
|
import android.content.Context; |
|
import android.util.SparseBooleanArray; |
|
import android.view.ActionMode; |
|
import android.view.Menu; |
|
import android.view.MenuItem; |
|
import android.view.ViewGroup; |
|
import android.widget.AbsListView.MultiChoiceModeListener; |
|
import android.widget.ListView; |
|
|
|
/** |
|
* A helper to implement {@link ListView} selection modification behaviour with the {@link SelectionModificationSpinner} |
|
* by implementing the specific actions and providing a title based on the number of currently selected items. It is |
|
* important that the provided list was instantiated already. |
|
* |
|
* @author Eric Kok |
|
*/ |
|
public class SelectionManagerMode implements MultiChoiceModeListener, OnModificationActionSelectedListener { |
|
|
|
private final Context themedContext; |
|
private final ListView managedList; |
|
private final int titleTemplateResource; |
|
private Class<?> onlyCheckClass = null; |
|
|
|
/** |
|
* Instantiates the helper by binding it to a specific {@link ListView} and providing the text resource to display |
|
* as title in the spinner. |
|
* |
|
* @param themedContext The context which is associated with the correct theme to apply when inflating views, i.e. the toolbar context |
|
* @param managedList The list to manage the selection for and execute selection action to |
|
* @param titleTemplateResource The string resource id to show as the spinners title; the number of selected items |
|
* will be supplied as numeric formatting argument |
|
*/ |
|
public SelectionManagerMode(Context themedContext, ListView managedList, int titleTemplateResource) { |
|
this.themedContext = themedContext; |
|
this.managedList = managedList; |
|
this.titleTemplateResource = titleTemplateResource; |
|
} |
|
|
|
/** |
|
* Set the class type of items that are allowed to be checked in the {@link ListView}. Defaults to null, which means |
|
* every list view row can be checked. |
|
* |
|
* @param onlyCheckClass The {@link Class} instance to use to check list item types against |
|
*/ |
|
public void setOnlyCheckClass(Class<?> onlyCheckClass) { |
|
this.onlyCheckClass = onlyCheckClass; |
|
} |
|
|
|
@Override |
|
public boolean onCreateActionMode(ActionMode mode, Menu menu) { |
|
// Allow modification of selection through a spinner |
|
SelectionModificationSpinner selectionSpinner = new SelectionModificationSpinner(themedContext); |
|
selectionSpinner.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, |
|
ViewGroup.LayoutParams.MATCH_PARENT)); |
|
selectionSpinner.setOnModificationActionSelectedListener(this); |
|
mode.setCustomView(selectionSpinner); |
|
return true; |
|
} |
|
|
|
@Override |
|
public boolean onPrepareActionMode(ActionMode mode, Menu menu) { |
|
return false; |
|
} |
|
|
|
@Override |
|
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { |
|
int checkedCount = 0; |
|
for (int i = 0; i < managedList.getCheckedItemPositions().size(); i++) { |
|
if (managedList.getCheckedItemPositions().valueAt(i) |
|
&& (onlyCheckClass == null || onlyCheckClass.isInstance(managedList.getItemAtPosition(managedList |
|
.getCheckedItemPositions().keyAt(i))))) |
|
checkedCount++; |
|
} |
|
((SelectionModificationSpinner) mode.getCustomView()).updateTitle(themedContext.getResources() |
|
.getQuantityString(titleTemplateResource, checkedCount, checkedCount)); |
|
} |
|
|
|
@Override |
|
public void onDestroyActionMode(ActionMode mode) { |
|
} |
|
|
|
@Override |
|
public boolean onActionItemClicked(ActionMode mode, MenuItem item) { |
|
return false; |
|
} |
|
|
|
/** |
|
* Implements the {@link SelectionModificationSpinner}'s invert selection command by flipping the checked status for |
|
* each (enabled) items in the {@link ListView}. |
|
*/ |
|
@Override |
|
public void invertSelection() { |
|
SparseBooleanArray checked = managedList.getCheckedItemPositions(); |
|
for (int i = 0; i < managedList.getAdapter().getCount(); i++) { |
|
if (managedList.getAdapter().isEnabled(i) |
|
&& (onlyCheckClass == null || onlyCheckClass.isInstance(managedList.getItemAtPosition(i)))) |
|
managedList.setItemChecked(i, !checked.get(i, false)); |
|
} |
|
} |
|
|
|
/** |
|
* Implements the {@link SelectionModificationSpinner}'s select all command by checking each (enabled) item in the |
|
* {@link ListView}. |
|
*/ |
|
@Override |
|
public void selectAll() { |
|
for (int i = 0; i < managedList.getAdapter().getCount(); i++) { |
|
if (managedList.getAdapter().isEnabled(i) |
|
&& (onlyCheckClass == null || onlyCheckClass.isInstance(managedList.getItemAtPosition(i)))) |
|
managedList.setItemChecked(i, true); |
|
} |
|
} |
|
|
|
/** |
|
* Implements the {@link SelectionModificationSpinner}'s select finished command by checking each (enabled) item |
|
* that represents something that is {@link Finishable} and indeed is finished; |
|
*/ |
|
@Override |
|
public void selectFinished() { |
|
for (int i = 0; i < managedList.getAdapter().getCount(); i++) { |
|
if (managedList.getAdapter().isEnabled(i) |
|
&& (onlyCheckClass == null || onlyCheckClass.isInstance(managedList.getItemAtPosition(i))) |
|
&& managedList.getItemAtPosition(i) instanceof Finishable) |
|
managedList.setItemChecked(i, ((Finishable) managedList.getItemAtPosition(i)).isFinished()); |
|
} |
|
} |
|
|
|
}
|
|
|