Eric Kok
12 years ago
6 changed files with 236 additions and 30 deletions
@ -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 @@ |
|||||||
|
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