1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.example.android.actionbarcompat.listviewmodalselect; 17 18 import android.os.Bundle; 19 import android.support.v4.app.ListFragment; 20 import android.support.v7.app.ActionBarActivity; 21 import android.support.v7.view.ActionMode; 22 import android.util.SparseBooleanArray; 23 import android.view.Menu; 24 import android.view.MenuItem; 25 import android.widget.ArrayAdapter; 26 import android.widget.BaseAdapter; 27 import android.widget.ListView; 28 29 import com.example.android.common.actionbarcompat.MultiSelectionUtil; 30 import com.example.android.common.dummydata.Cheeses; 31 32 import java.util.ArrayList; 33 import java.util.Iterator; 34 35 /** 36 * This ListFragment displays a list of cheeses, allowing the user to select multiple items 37 * in a modal selection mode. In this example, the user can remove multiple items via the displayed 38 * action mode. 39 */ 40 public class CheeseListFragment extends ListFragment { 41 42 // ArrayList containing the cheese name Strings 43 private ArrayList<String> mItems; 44 45 // The Controller which provides CHOICE_MODE_MULTIPLE_MODAL-like functionality 46 private MultiSelectionUtil.Controller mMultiSelectController; 47 48 @Override 49 public void onActivityCreated(Bundle savedInstanceState) { 50 super.onActivityCreated(savedInstanceState); 51 52 // The items which will be displayed 53 mItems = Cheeses.asList(); 54 55 // Set the ListAdapter so that the ListView displays the items 56 setListAdapter(new ArrayAdapter<String>(getActivity(), R.layout.simple_selectable_list_item, 57 android.R.id.text1, mItems)); 58 59 // BEGIN_INCLUDE(attach_controller) 60 // Attach a MultiSelectionUtil.Controller to the ListView, giving it an instance of 61 // ModalChoiceListener (see below) 62 mMultiSelectController = MultiSelectionUtil 63 .attachMultiSelectionController(getListView(), (ActionBarActivity) getActivity(), 64 new ModalChoiceListener()); 65 66 // Allow the Controller to restore itself 67 mMultiSelectController.restoreInstanceState(savedInstanceState); 68 // END_INCLUDE(attach_controller) 69 } 70 71 @Override 72 public void onSaveInstanceState(Bundle outState) { 73 super.onSaveInstanceState(outState); 74 75 // BEGIN_INCLUDE(save_instance) 76 // Allow the Controller to save it's instance state so that any checked items are 77 // stored 78 if (mMultiSelectController != null) { 79 mMultiSelectController.saveInstanceState(outState); 80 } 81 // END_INCLUDE(save_instance) 82 } 83 84 /** 85 * The listener which is provided to MultiSelectionUtil to handle any multi-selection actions. 86 * It is responsible for providing the menu to display on the action mode, and handling any 87 * action item clicks. 88 */ 89 private class ModalChoiceListener implements MultiSelectionUtil.MultiChoiceModeListener { 90 91 @Override 92 public void onItemCheckedStateChanged(ActionMode mode, int position, long id, 93 boolean checked) { 94 } 95 96 @Override 97 public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { 98 // Inflate the menu resource (res/menu/context_cheeses.xml) which will be displayed 99 // in the action mode 100 actionMode.getMenuInflater().inflate(R.menu.context_cheeses, menu); 101 return true; 102 } 103 104 @Override 105 public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) { 106 return true; 107 } 108 109 @Override 110 public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) { 111 // We switch on the menu item's id, so we know which is clicked 112 switch (menuItem.getItemId()) { 113 114 // Our item with the menu_remove ID is used to remove the item(s) from the list. 115 // Here we retrieve which positions are currently checked, then iterate through the 116 // list and remove the checked items. Once finished we notify the adapter to update 117 // the ListView contents and finish the action mode. 118 case R.id.menu_remove: 119 // Retrieve which positions are currently checked 120 final ListView listView = getListView(); 121 SparseBooleanArray checkedPositions = listView.getCheckedItemPositions(); 122 123 // Check to see if there are any checked items 124 if (checkedPositions.size() == 0) { 125 return false; 126 } 127 128 // Iterate through the items and remove any which are checked 129 final Iterator<String> iterator = mItems.iterator(); 130 int i = 0; 131 while (iterator.hasNext()) { 132 // Call next() so that the iterator index moves 133 iterator.next(); 134 135 // Remove the item if it is checked (and increment position) 136 if (checkedPositions.get(i++)) { 137 iterator.remove(); 138 } 139 } 140 141 // Clear the ListView's checked items 142 listView.clearChoices(); 143 144 // Finally, notify the adapter so that it updates the ListView 145 ((BaseAdapter) getListAdapter()).notifyDataSetChanged(); 146 147 // As we're removing all of checked items, we'll close the action mode 148 actionMode.finish(); 149 150 // We return true to signify that we have handled the action item click 151 return true; 152 } 153 154 return false; 155 } 156 157 @Override 158 public void onDestroyActionMode(ActionMode actionMode) { 159 } 160 } 161 }