Home | History | Annotate | Download | only in listviewmodalselect
      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 }