Activate CAB menu when OnClickEvent happens in Android - android

Trying to activate CAB menu when clicking on MenuItem from ActionBar. Here is how I set the GridView for listening to Multi Choice. The multiModeChoiceListener is working fine when I long press on Any item in the GridView. It is working fine. Now I have a requirement to activate the CAB menu when do press on a menu item in Action Bar. Once it is pressed, the CAB menu should read that 0 items are selected. After that it should allow me to select items from GridView on single clicks. How can I achieve this feature?
GridView set listener:
gv.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL);
gv.setMultiChoiceModeListener(new MultiChoiceModeListener());
MultiChoiceModeListener.java
public class MultiChoiceModeListener implements
GridView.MultiChoiceModeListener {
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.featured_multiselect, menu);
MenuItem mi = menu.findItem(R.id.close);
mi.setIcon(R.drawable.cancel);
mode.setTitle("Select Items");
return true;
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return true;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Toast.makeText(getApplicationContext(), item.getTitle(),
Toast.LENGTH_SHORT).show();
if (item.getTitle().toString().equalsIgnoreCase("Close")) {
mode.finish();
}
return true;
}
public void onDestroyActionMode(ActionMode mode) {
new ChangeNotifier().changeOnFavoriteStore = true;
new AddFavorites().execute("add", device_id, dataArray);
if (notify == true) {
Toast.makeText(getApplicationContext(),
"Selected items are added to Favorites",
Toast.LENGTH_SHORT).show();
notify = false;
}
}
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
int selectCount = gridView.getCheckedItemCount();
if (selectCount > 0) {
notify = true;
dataArray.add(position);
switch (selectCount) {
case 1:
mode.setSubtitle("One item added to favorites");
break;
default:
mode.setSubtitle("" + selectCount
+ " items added to favorites");
break;
}
}
}
OnMenuItemClick method:
public boolean onPrepareOptionsMenu(final Menu menu) {
final MenuItem editItem = menu.findItem(R.id.editit);
editItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
//the CAB menu should be activated here. So that it reads that 0 items are selected in ActionBar
return false;
}
});

From your question I understand that you're trying to start the GridView associated CAB from clicking one of the menu items. I don't know if you can do this(but I may be mistaken) as the MultiChoiceModeListener expects an item to be checked to start. Depending on your layout and the overall appearance of the GridView, I think you could have a dummy item(as an extra item in the adapter) at the end of the GridView(with no content showing) and use setItemChecked(dummyItemPosition, true) to start the GridView CAB. Of course you'll need to have additional logic to take care of that extra item in your MultiChoiceModeListener:
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
if (position == theDummyPosition)
return; // so we start the CAB but there aren't any items checked
}
int selectCount = gridView.getCheckedItemCount();
if (selectCount > 0) {
notify = true;
dataArray.add(position);
// if you select another item you'll have two selected items(because of the dummy item) so you need to take care of it
switch (selectCount) {
case 1:
mode.setSubtitle("One item added to favorites");
break;
default:
mode.setSubtitle("" + selectCount
+ " items added to favorites");
break;
}
}
}
The solution above is a hack, most likely it would be much easier to lose the MultiChoiceModeListener and simply start an ActionMode that you can manipulate for both situations.

Related

setBackgroundResource in onItemCheckStateChanged doesn't work for the first selection

I am working on an android project where I have a grid view and I am setting it up with a MultiChoiceModeListener.
When I long click, it successfully creates the contextual action bar but setting the setBackgroundResource on the initial item that creates the CAB doesn't have any affect, however all subsequent items that are selected, the background resource is successfully applied. Below is the code I am using:
gridView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL);
gridView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener()
{
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked)
{
Log.d("DirectoryPicker-CAB", "CheckedStateChanged");
//findViewById((int)gridView.getItemIdAtPosition(position)).setBackgroundColor(ContextCompat.getColor(DirectoryPicker.this, R.color.appPrimaryColour));
//Toast.makeText(DirectoryPicker.this, "Item CAB Clicked: Checked: " + (checked ? "true" : "false"), Toast.LENGTH_LONG).show();
Toast.makeText(DirectoryPicker.this, "Position: " + position, Toast.LENGTH_LONG).show();
if (checked)
{
//gridView.getChildAt(position).setBackgroundColor(ContextCompat.getColor(DirectoryPicker.this, R.color.appPrimaryColour));
Log.d("DirectoryPicker-View", gridView.getChildAt(position).toString());
gridView.getChildAt(position).setBackgroundResource(R.color.appPrimaryColour);
mode.invalidate();
directoryAdapter.getItem(position).setSelected(true);
selectedDirectories.add(directoryAdapter.getItem(position));
}
else
{
directoryAdapter.getItem(position).setSelected(false);
FileManager.DirectoryOrFileInfo selectedDirectory = directoryAdapter.getItem(position);
for (int i = 0; i < selectedDirectories.size(); i++)
{
if (selectedDirectories.get(i) == selectedDirectory)
{
selectedDirectories.remove(i);
selectedDirectory.setSelected(false);
}
}
gridView.getChildAt(position).setBackgroundColor(ContextCompat.getColor(DirectoryPicker.this, android.R.color.transparent));
}
mode.setTitle(selectedDirectories.size() + " selected");
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.file_dir_cab_menu, menu);
Log.d("DirectoryPicker-CAB", "OnActionModeCreate");
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu)
{
return true;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item)
{
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode)
{
selectedDirectories.clear();
}
});
Why does the background resource not get successfully applied for the first item that is long clicked that creates the CAB, but it works fine for all subsequent selections.
I've figured why this isn't working now. When the CAB is created, it triggers the getView function to be called again in my adapter so it ends up resetting the view back to how it was again.
I've therefore changed my adapter instead in the getView method so it checks whether the item is marked as checked, and it sets the background resource.

Android CAB destroying after listview notifydatasetchanged

I am using setMultiChoiceModeListener on Listview to invoke Action Mode for selecting multiple items to be deleted. On ListView scroll I load more data from server and notify the adapter. After adapter has been notified, the Action Mode (if invoked) is destroyed and recreated, which makes the title and selected arraylist empty (You can see the picture below). While the listview item selection remains. I want the CAB to be persistent like we see it in Gmail app, where it does not destroy on loading more data.
Below is the code for Action Mode
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
Item mItem = adapter.items.get(position);
if (mItem.isSection()) {
} else {
mode.setTitle(listView.getCheckedItemCount() + " Selected");
EntryItem mEntryItem = (EntryItem) mItem;
orderid = mEntryItem.orderId;
if (checked) {
selectedIdList.add(orderid);
} else {
selectedIdList.remove(orderid);
}
// Toggle the state of item after every click on it
adapter.toggleSelection(position);
}
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.delete){
if (selectedIdList.size() > 0) {
deleteItems(selectedIdList);
}
mode.finish();
return true;
}
return false;
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.menu_main, menu);
actionMode = mode;
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
if (selectedIdList.size() > 0) {
selectedIdList.clear();
adapter.mSelectedItemsIds.clear();
}
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
});
Any help will be highly appreciated, thanks in advance.
You need to save selected items id in order to retain state and show as selected after you refresh/notify adapter changes like shown in below examples:
1) https://androidperspective.wordpress.com/2013/04/17/contextual-action-bar-with-listview/
(It shows selection and saving selected item ids in array to save state).
2) http://theopentutorials.com/examples/android/listview/android-contextual-action-bar-for-listview-item-deletion-using-actionbarsherlock/
(It shows complete example you want for deletion just using sherlock action bar it would be little change only).
Glad to know if it helps you.

multiple selection listview with custom layout

I want custom ListView layout which has multiple selection , so I am doing custom adapter but how I can allow user to select multiple . In default ListView we are given choice mode but I want layout different not checkbook
<Imageview>
<Textview>
Do I have to manage in onItemClick or any method is der ? Small snippet will help
For this you need ListView.CHOICE_MODE_MULTIPLE_MODAL. See the following code snippet,
First create a ListView and it's adapter,
listView = (ListView) findViewById(R.id.listView);
adapter = new AttendanceListAdapter(this, attendanceList);
Set the List choice mode to multiple and add a Multi choice listener,
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new ModeCallback());
listView.setAdapter(adapter);
Your Multi choice listener should look something like this,
private class ModeCallback implements ListView.MultiChoiceModeListener {
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.list_select_menu, menu);
mode.setTitle("Select Items");
return true;
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return true;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.share:
Toast.makeText(AddAttendanceActivity.this, "Shared " + listView.getCheckedItemCount() +
" items", Toast.LENGTH_SHORT).show();
mode.finish();
break;
default:
Toast.makeText(AddAttendanceActivity.this, "Clicked " + item.getTitle(),
Toast.LENGTH_SHORT).show();
break;
}
return true;
}
public void onDestroyActionMode(ActionMode mode) {
}
public void onItemCheckedStateChanged(ActionMode mode,
int position, long id, boolean checked) {
final int checkedCount = listView.getCheckedItemCount();
switch (checkedCount) {
case 0:
mode.setSubtitle(null);
break;
case 1:
mode.setSubtitle("One item selected");
break;
default:
mode.setSubtitle("" + checkedCount + " items selected");
break;
}
}
}
Now if you want the selected rows to highlighted add this style to the root element of your list items layout.
<style name="activated" parent="AppTheme">
<item name="android:background">?android:attr/activatedBackgroundIndicator</item>
</style>
I think you you want something like whatsup select for that on long click listener you can change color of custom listview items(rows)

Android ListView Single Choice Mode with Action Mode

I would like to create an app screen that include one ListView.
When the user performs long press on ListView item, I would like to show action mode. I implemented it with the following code and I got the result which I want.
One problem is that I would like to allow the user to select only one list item and select the context menu item in action mode to do the operation. The following code is allowed the user to select multiple list items.
Is android not support ListView.CHOICE_MODE_SINGLE_MODAL choice mode? I had spend a lot of time in Googling but can't find any reference to implement which allows a single choice mode with context action mode. Please help.
mTestListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mTestListView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode actionMode, int position, long l, boolean value) {
}
#Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuInflater inflater = actionMode.getMenuInflater();
inflater.inflate(R.menu.context_menu_test_single_choice_mode, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_done:
Toast.makeText(getActivity(), "Done", Toast.LENGTH_SHORT).show();
actionMode.finish();
adapter.notifyDataSetChanged();
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(ActionMode actionMode) {
}
});
}
Add this code in your method. This code will check item count. If count exceed more than one, it will remove other item except the last one.
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
int selectCount = mList.getCheckedItemCount();
if(selectCount > 1){
SparseBooleanArray checkarr = mList.getCheckedItemPositions();
for(int i=0;i<dataList.size();i++){
/*
check item is checked
and not the last item
* */
if(checkarr.get(i) && position != i){
mList.setItemChecked(i, false);
break;
}
}
}
}
I tried in my app. It works. :). Hope this will help you.

Batch contextual action mode

I want to enable multiple view selection on longClick(). Should I declare an action mode object and call startActionMode()? Also, how would I change menu list for single item click? I used the documentation as reference, as shown.
ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
// Here you can do something when items are selected/de-selected,
// such as update the title in the CAB
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Respond to clicks on the actions in the CAB
switch (item.getItemId()) {
case R.id.menu_delete:
deleteSelectedItems();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate the menu for the CAB
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context, menu);
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
// Here you can make any necessary updates to the activity when
// the CAB is removed. By default, selected items are deselected/unchecked.
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// Here you can perform updates to the CAB due to
// an invalidate() request
return false;
}
});
To change menu list for single item click following is the code.
int count=0;
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
if (checked) {
count++;
} else {
count--;
}
mode.invalidate(); // Add this to Invalidate CAB so that it calls onPrepareActionMode
}
Now modify the onPrepareActionMode as follows
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
if (selCount == 1){
//show the menu here that you want if only 1 item is selected
} else {
//show the menu here that you want if more than 1 item is selected
}
}

Categories

Resources