From 6e5365a8e8d5026297abbcd6e11c4048310c8387 Mon Sep 17 00:00:00 2001 From: Jimmy Shih Date: Thu, 20 Jun 2013 13:17:15 -0700 Subject: [PATCH] Move select all in multiple select to an action bar item --- .../res/drawable-hdpi/menu_select_all.png | Bin 0 -> 1455 bytes .../res/drawable-mdpi/menu_select_all.png | Bin 0 -> 1339 bytes .../res/drawable-xhdpi/menu_select_all.png | Bin 0 -> 1583 bytes MyTracks/res/menu/list_context_menu.xml | 5 ++ MyTracks/res/values/strings.xml | 16 ++-- .../ContextualActionModeCallback.java | 3 +- .../apps/mytracks/MarkerListActivity.java | 22 +++++- .../apps/mytracks/SearchListActivity.java | 7 +- .../apps/mytracks/TrackListActivity.java | 14 +++- .../apps/mytracks/util/Api11Adapter.java | 73 +----------------- 10 files changed, 50 insertions(+), 90 deletions(-) create mode 100644 MyTracks/res/drawable-hdpi/menu_select_all.png create mode 100644 MyTracks/res/drawable-mdpi/menu_select_all.png create mode 100644 MyTracks/res/drawable-xhdpi/menu_select_all.png diff --git a/MyTracks/res/drawable-hdpi/menu_select_all.png b/MyTracks/res/drawable-hdpi/menu_select_all.png new file mode 100644 index 0000000000000000000000000000000000000000..26a270b33a56e47db2da491a79e73f25c25f9aee GIT binary patch literal 1455 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%qp275hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s00+w{G(#^lGsViy#L3CR%*fHy$-vFf(ACh=#L&{!#L3yw z&D7A`#K{n**Cju>G&eP`1g19yq1OqgUQlAlEdbi=l3J8mmYU*Ll%J~r_Ow+dZns$A zG!Lpb1-Dx)aq86vIz}H9wMbD769T3m5EGtofgE_!Pt60S_ab1zzQwoT5Ca2~qNj^v zNX4x;GxvKRb`Uv!IVf3l>E;lpa(8jfKE7G|7h3G%axamS{p*Yeu0ThyC0g}o3954It?dms^>B2c{-0zbq6W@@j(EftxRvINg5P zy8Uu1hqdgHw=9gFm5RYD7Vj&mzmooMD_8pR$z3k;{SCLV@IujUrJ S*u5zP6``K4elF{r5}E*Q1s{q4 literal 0 HcmV?d00001 diff --git a/MyTracks/res/drawable-mdpi/menu_select_all.png b/MyTracks/res/drawable-mdpi/menu_select_all.png new file mode 100644 index 0000000000000000000000000000000000000000..070593ff867bb6b0b266c67053dd61cd48263653 GIT binary patch literal 1339 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%qp275hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s00+w{G(#^lGsViy#L3CR%*fT$$-vFf(ACh=#L&{!#L3yw z&D7A`#K{n**Cju>G&eP`1g19yq1O$kUQlAlEdbi=l3J8mmYU*Ll%J~r_Ow+dZnrq& zG!Lpb1-DyVaO%|uIz}H9wMbD769T3m5EGtofgE_!Pt60S_ab1z4q@*?Yc zQgQ3e^u2k93`AOGMV9;vSXkE9>vMP4GVg1AGox4XAK?C?S-~i`KxnRH!kZw&vezNU z&MjE=#a%0?N@*^~@uC6`nZ^*E+M=5LlG=^^`8~p}6K|xg?$q60%e0F{?Et%?M6=rO z4NK0ZzX>TeQQE_z|3ISRLFcycU){It4qE1}7E@m!(6sGX+%&V~aa>uhDiihjD z?J~Fz$nKb=UTo@pb$ZK`H4ZX=d}ca$?7#Iyyys@PdU5f)`$10Io_@^_Vc%urv~Bis z;e~muc^Xb%ZMPqZ`0&U6d1NDFcl(-W5dp@nmbGg8V;-Rdelc-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%uvD1M9IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr4|esh**NZ(?$0 z9!LbN!`Ii!Gq1QLF)umQ)5TT^Xog;9W{Q=YiIbCsnUR^PlYyI|p{t>#iJ_&diIcOV zo2j9>iIX8ruSMv>2~2MaLa#Yay`aR9TL84#CABECEH%ZgC_h&L>}jh^tZp$j zHZU=8!D${;Zwgkofc3iK)TkpMZkpJFZHvV zfq`kEr;B4q#jQ6{r?aFDMP&OAJA63i%hg)rpzyOHz)A6f{0sh)+u|1UCrsV1VBtCW zQfhdk(5voc}s?BHyK}7iFii zH9H2Ra5p#27EoZ}V03B#Qasz$E-<~S>1){jW$*L)mOu9%<)jep#*I_{aQ$KCGmXDiSoHHSQCAt6iU!B2xMW|xpv<6YNgZnuPrwXzebbi~V%jBPXoG2ZRbNdzpXfX-1f|pT>EW8CYF5Dx2oLu zo|4&qtMEtIqy#sw3rnjUo_Sr^TIHYzW`oHFje~*PxP?`J1ZwyENHG0YdH$G?L1>d+ zq@Jncbf2uI#w#qF!=c<)j5{?Prvu47vSlv~QvQ_f_^|%CD`%IG&JH1ylZ?T&zJ7XM zQb$&FAAhy#js64X+bgOoPT$FYJYDs5Om+K}M;nz+8@-cFe_8yXu%JG)EcwNYD?Ae)qS{Lu*t5r9fl + \ No newline at end of file diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml index b9861dbe4..479c302de 100644 --- a/MyTracks/res/values/strings.xml +++ b/MyTracks/res/values/strings.xml @@ -953,19 +953,11 @@ limitations under the License. - - Deselect all - %1$d selected - - Select all - Search + + Select all + No email addresses entered. - + diff --git a/MyTracks/src/com/google/android/apps/mytracks/ContextualActionModeCallback.java b/MyTracks/src/com/google/android/apps/mytracks/ContextualActionModeCallback.java index 1e0df4c0d..27e926d69 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/ContextualActionModeCallback.java +++ b/MyTracks/src/com/google/android/apps/mytracks/ContextualActionModeCallback.java @@ -31,8 +31,9 @@ public interface ContextualActionModeCallback { * @param menu the menu * @param positions the selected items' positions * @param ids the selected items' ids, if available + * @param showSelectAll true to show select all */ - public void onPrepare(Menu menu, int[] positions, long[] ids); + public void onPrepare(Menu menu, int[] positions, long[] ids, boolean showSelectAll); /** * Invoked when items are selected. diff --git a/MyTracks/src/com/google/android/apps/mytracks/MarkerListActivity.java b/MyTracks/src/com/google/android/apps/mytracks/MarkerListActivity.java index a0ab8825f..a29f7f675 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/MarkerListActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/MarkerListActivity.java @@ -69,13 +69,19 @@ public class MarkerListActivity extends AbstractMyTracksActivity implements Dele private ContextualActionModeCallback contextualActionModeCallback = new ContextualActionModeCallback() { @Override - public void onPrepare(Menu menu, int[] positions, long[] ids) { + public void onPrepare(Menu menu, int[] positions, long[] ids, boolean showSelectAll) { menu.findItem(R.id.list_context_menu_play).setVisible(false); menu.findItem(R.id.list_context_menu_share).setVisible(false); menu.findItem(R.id.list_context_menu_show_on_map).setVisible(ids.length == 1); menu.findItem(R.id.list_context_menu_edit) .setVisible(ids.length == 1 && !track.isSharedWithMe()); menu.findItem(R.id.list_context_menu_delete).setVisible(!track.isSharedWithMe()); + /* + * Set select all to the same visibility as delete since delete is the + * only action that can be applied to multiple markers. + */ + menu.findItem(R.id.list_context_menu_select_all) + .setVisible(showSelectAll && !track.isSharedWithMe()); } @Override @@ -125,6 +131,7 @@ public class MarkerListActivity extends AbstractMyTracksActivity implements Dele private ResourceCursorAdapter resourceCursorAdapter; // UI elements + private ListView listView; private MenuItem insertMarkerMenuItem; private MenuItem searchMenuItem; @@ -144,7 +151,7 @@ public class MarkerListActivity extends AbstractMyTracksActivity implements Dele setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); - ListView listView = (ListView) findViewById(R.id.marker_list); + listView = (ListView) findViewById(R.id.marker_list); listView.setEmptyView(findViewById(R.id.marker_list_empty)); listView.setOnItemClickListener(new OnItemClickListener() { @Override @@ -257,9 +264,10 @@ public class MarkerListActivity extends AbstractMyTracksActivity implements Dele public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); getMenuInflater().inflate(R.menu.list_context_menu, menu); - + AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; - contextualActionModeCallback.onPrepare(menu, new int[] {info.position}, new long[] {info.id}); + contextualActionModeCallback.onPrepare( + menu, new int[] { info.position }, new long[] { info.id }, false); } @Override @@ -299,6 +307,12 @@ public class MarkerListActivity extends AbstractMyTracksActivity implements Dele DeleteMarkerDialogFragment.newInstance(markerIds) .show(getSupportFragmentManager(), DeleteMarkerDialogFragment.DELETE_MARKER_DIALOG_TAG); return true; + case R.id.list_context_menu_select_all: + int size = listView.getCount(); + for (int i = 0; i < size; i++) { + listView.setItemChecked(i, true); + } + return false; default: return false; } diff --git a/MyTracks/src/com/google/android/apps/mytracks/SearchListActivity.java b/MyTracks/src/com/google/android/apps/mytracks/SearchListActivity.java index cda634e6d..696c81a41 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/SearchListActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/SearchListActivity.java @@ -133,7 +133,7 @@ public class SearchListActivity extends AbstractSendToGoogleActivity return handleContextItem(itemId, positions); } @Override - public void onPrepare(Menu menu, int[] positions, long[] ids) { + public void onPrepare(Menu menu, int[] positions, long[] ids, boolean showSelectAll) { boolean shareWithMe = true; Long markerId = null; if (positions.length == 1) { @@ -158,6 +158,8 @@ public class SearchListActivity extends AbstractSendToGoogleActivity // Only one item. If marker, cannot be a shareWithMe item. If track, no restriction menu.findItem(R.id.list_context_menu_delete) .setVisible(positions.length == 1 && (markerId == null || !shareWithMe)); + // Disable select all, no action is available for multiple selection + menu.findItem(R.id.list_context_menu_select_all).setVisible(false); } }; @@ -296,7 +298,8 @@ public class SearchListActivity extends AbstractSendToGoogleActivity getMenuInflater().inflate(R.menu.list_context_menu, menu); AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; - contextualActionModeCallback.onPrepare(menu, new int[] {info.position}, new long[] {info.id}); + contextualActionModeCallback.onPrepare( + menu, new int[] { info.position }, new long[] { info.id }, false); } @Override diff --git a/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java b/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java index 92f747c36..4a0f6105f 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java @@ -211,16 +211,18 @@ public class TrackListActivity extends AbstractSendToGoogleActivity contextualActionModeCallback = new ContextualActionModeCallback() { @Override - public void onPrepare(Menu menu, int[] positions, long[] ids) { + public void onPrepare(Menu menu, int[] positions, long[] ids, boolean showSelectAll) { boolean shareWithMe = true; if (ids.length == 1) { Track track = myTracksProviderUtils.getTrack(ids[0]); shareWithMe = track.isSharedWithMe(); } + // play is always enabled menu.findItem(R.id.list_context_menu_share).setVisible(!shareWithMe); menu.findItem(R.id.list_context_menu_show_on_map).setVisible(false); menu.findItem(R.id.list_context_menu_edit).setVisible(!shareWithMe); - menu.findItem(R.id.list_context_menu_delete).setVisible(true); + // delete is always enabled + menu.findItem(R.id.list_context_menu_select_all).setVisible(showSelectAll); } @Override @@ -565,7 +567,7 @@ public class TrackListActivity extends AbstractSendToGoogleActivity AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; contextualActionModeCallback.onPrepare( - menu, new int[] { info.position }, new long[] { info.id }); + menu, new int[] { info.position }, new long[] { info.id }, false); } @Override @@ -770,6 +772,12 @@ public class TrackListActivity extends AbstractSendToGoogleActivity DeleteTrackDialogFragment.newInstance(deleteAll, trackIds) .show(getSupportFragmentManager(), DeleteTrackDialogFragment.DELETE_TRACK_DIALOG_TAG); return true; + case R.id.list_context_menu_select_all: + int size = listView.getCount(); + for (int i = 0; i < size; i++) { + listView.setItemChecked(i, true); + } + return false; default: return false; } diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/Api11Adapter.java b/MyTracks/src/com/google/android/apps/mytracks/util/Api11Adapter.java index 5c2c531f4..8cda96100 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/Api11Adapter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/Api11Adapter.java @@ -30,16 +30,11 @@ import android.view.ActionMode; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; import android.widget.AbsListView.MultiChoiceModeListener; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.SearchView; -import android.widget.Spinner; import android.widget.TabWidget; -import android.widget.TextView; import java.util.ArrayList; import java.util.List; @@ -74,58 +69,6 @@ public class Api11Adapter extends Api10Adapter { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { mode.getMenuInflater().inflate(R.menu.list_context_menu, menu); - final Spinner spinner = new Spinner(activity) { - @Override - public void setSelection(int position) { - super.setSelection(position); - // Fire event when selecting the same item - if (position == getSelectedItemPosition()) { - getOnItemSelectedListener() - .onItemSelected(this, getSelectedView(), position, getSelectedItemId()); - } - } - }; - ArrayAdapter adapter = new ArrayAdapter( - activity, android.R.layout.simple_spinner_item, - new StringBuilder[] { new StringBuilder("") }) { - @Override - public View getDropDownView(int position, View convertView, ViewGroup parent) { - // Display select all/ deselect all - View view = super.getDropDownView(position, convertView, parent); - TextView textView = (TextView) view; - int messageId = listView.getCheckedItemCount() == listView.getCount() - ? R.string.list_deselect_all - : R.string.list_select_all; - textView.setText(messageId); - return view; - }; - }; - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - spinner.setAdapter(adapter); - - // Use a post to prevent the spinner item from firing when first created - spinner.post(new Runnable() { - @Override - public void run() { - spinner.setOnItemSelectedListener(new OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - // Handle select all/ deselect all - int size = listView.getCount(); - boolean allSelected = listView.getCheckedItemCount() == size; - for (int i = 0; i < size; i++) { - listView.setItemChecked(i, !allSelected); - } - } - - @Override - public void onNothingSelected(AdapterView parent) { - // Do nothing - } - }); - } - }); - mode.setCustomView(spinner); setActionModeTitle(mode); return true; } @@ -133,7 +76,7 @@ public class Api11Adapter extends Api10Adapter { @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { contextualActionModeCallback.onPrepare( - menu, getCheckedPositions(listView), listView.getCheckedItemIds()); + menu, getCheckedPositions(listView), listView.getCheckedItemIds(), true); return true; } @@ -142,18 +85,10 @@ public class Api11Adapter extends Api10Adapter { // Do nothing } - @SuppressWarnings("unchecked") @Override public void onItemCheckedStateChanged( ActionMode mode, int position, long id, boolean checked) { setActionModeTitle(mode); - - // Update action mode title - Spinner spinner = (Spinner) mode.getCustomView(); - ArrayAdapter adapter = (ArrayAdapter) spinner.getAdapter(); - adapter.notifyDataSetChanged(); - - // Update contextual action mode items mode.invalidate(); } @@ -172,12 +107,8 @@ public class Api11Adapter extends Api10Adapter { * @param mode action mode */ private void setActionModeTitle(ActionMode mode) { - Spinner spinner = (Spinner) mode.getCustomView(); - StringBuilder stringBuilder = (StringBuilder) spinner.getSelectedItem(); - stringBuilder.delete(0, stringBuilder.length()); - int count = listView.getCheckedItemCount(); - stringBuilder.append(activity.getString(R.string.list_item_selected, count)); + mode.setTitle(activity.getString(R.string.list_item_selected, count)); } /**