• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.AppCompatActivity;
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
onActivityCreated(Bundle savedInstanceState)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(), (AppCompatActivity) 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
onSaveInstanceState(Bundle outState)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
onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked)92         public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
93                 boolean checked) {
94         }
95 
96         @Override
onCreateActionMode(ActionMode actionMode, Menu menu)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
onPrepareActionMode(ActionMode actionMode, Menu menu)105         public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
106             return true;
107         }
108 
109         @Override
onActionItemClicked(ActionMode actionMode, MenuItem menuItem)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
onDestroyActionMode(ActionMode actionMode)158         public void onDestroyActionMode(ActionMode actionMode) {
159         }
160     }
161 }
162