Eric Kok
12 years ago
6 changed files with 236 additions and 30 deletions
@ -0,0 +1,110 @@
@@ -0,0 +1,110 @@
|
||||
package org.transdroid.core.gui.navigation; |
||||
|
||||
import org.transdroid.core.gui.navigation.SelectionModificationSpinner.OnModificationActionSelectedListener; |
||||
|
||||
import android.util.SparseBooleanArray; |
||||
import android.view.ViewGroup; |
||||
import android.widget.ListView; |
||||
|
||||
import com.actionbarsherlock.view.ActionMode; |
||||
import com.actionbarsherlock.view.Menu; |
||||
import com.actionbarsherlock.view.MenuItem; |
||||
import com.actionbarsherlock.view.SherlockListView.MultiChoiceModeListenerCompat; |
||||
|
||||
/** |
||||
* 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 MultiChoiceModeListenerCompat, OnModificationActionSelectedListener { |
||||
|
||||
private ListView managedList; |
||||
private 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 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(ListView managedList, int titleTemplateResource) { |
||||
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(managedList.getContext()); |
||||
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)) |
||||
checkedCount++; |
||||
} |
||||
((SelectionModificationSpinner) mode.getCustomView()).updateTitle(managedList.getContext().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 selectionAll() { |
||||
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); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,98 @@
@@ -0,0 +1,98 @@
|
||||
package org.transdroid.core.gui.navigation; |
||||
|
||||
import org.transdroid.core.R; |
||||
|
||||
import android.content.Context; |
||||
import android.view.View; |
||||
import android.view.ViewGroup; |
||||
import android.widget.ArrayAdapter; |
||||
import android.widget.Spinner; |
||||
import android.widget.TextView; |
||||
|
||||
/** |
||||
* Spinner that holds actions that can be performed on list selections. The spinner itself has some title, which can for |
||||
* example be used to show the number of selected items. |
||||
* @author Eric Kok |
||||
*/ |
||||
public class SelectionModificationSpinner extends Spinner { |
||||
|
||||
private SelectionDropDownAdapter selectionAdapter; |
||||
private OnModificationActionSelectedListener onModificationActionSelected = null; |
||||
|
||||
/** |
||||
* Instantiates a spinner that contains some fixed actions for a user to modify selections. |
||||
* @param context The interface context where the spinner will be shown in |
||||
*/ |
||||
public SelectionModificationSpinner(Context context) { |
||||
super(context); |
||||
selectionAdapter = new SelectionDropDownAdapter(context); |
||||
setAdapter(selectionAdapter); |
||||
} |
||||
|
||||
/** |
||||
* Updates the fixed title text shown in the spinner, regardless of spinner item action selection. |
||||
* @param title The new static string to show, such as the number of selected items |
||||
*/ |
||||
public void updateTitle(String title) { |
||||
selectionAdapter.titleView.setText(title); |
||||
invalidate(); |
||||
} |
||||
|
||||
/** |
||||
* Sets the listener for action selection events. |
||||
* @param onModificationActionSelected The listener that handles performing of the actions as selected in this |
||||
* spinner by the user |
||||
*/ |
||||
public void setOnModificationActionSelectedListener(OnModificationActionSelectedListener onModificationActionSelected) { |
||||
this.onModificationActionSelected = onModificationActionSelected; |
||||
} |
||||
|
||||
@Override |
||||
public void setSelection(int position) { |
||||
if (position == 0) { |
||||
onModificationActionSelected.selectionAll(); |
||||
} else if (position == 1) { |
||||
onModificationActionSelected.invertSelection(); |
||||
} |
||||
super.setSelection(position); |
||||
} |
||||
|
||||
/** |
||||
* Local adapter that holds the actions which can be performed and a title text view that always shows instead of a |
||||
* list item as in a normal spinner. |
||||
*/ |
||||
private class SelectionDropDownAdapter extends ArrayAdapter<String> { |
||||
|
||||
protected TextView titleView = null; |
||||
|
||||
public SelectionDropDownAdapter(Context context) { |
||||
super(context, android.R.layout.simple_list_item_1, new String[] { |
||||
context.getString(R.string.navigation_selectall), |
||||
context.getString(R.string.navigation_invertselection) }); |
||||
titleView = new TextView(getContext()); |
||||
} |
||||
|
||||
@Override |
||||
public View getView(int position, View convertView, ViewGroup parent) { |
||||
// This returns the singleton text view showing the title with the number of selected items
|
||||
return titleView; |
||||
} |
||||
|
||||
@Override |
||||
public View getDropDownView(int position, View convertView, ViewGroup parent) { |
||||
// This returns the actions to show in the spinner list
|
||||
return super.getView(position, convertView, parent); |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Interface to implement if an interface want to respond to selection modification actions. |
||||
*/ |
||||
public interface OnModificationActionSelectedListener { |
||||
public void invertSelection(); |
||||
|
||||
public void selectionAll(); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue