I have read a lot of threads here about listviews and checkboxes. Lots of them use a CheckedTextView or extend it. I want to implement a custom listview with a checkbox behaviour like on the android mail apps (Gingerbread, ICS): There only checkboxes are checkable and not the whole row. Plus on ICS the actionbar indicates the number of checked list items.
Can anyone please show me some code or point me in the right direction? Thanks!
Checkout out the sample in API Demos List 16 Multi selection mode
public class List16 extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView lv = getListView();
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
lv.setMultiChoiceModeListener(new ModeCallback());
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_activated_1,
Cheeses.sCheeseStrings));
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
getActionBar().setSubtitle("Long press to start selection");
}
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(List16.this, "Shared " + getListView().
getCheckedItemCount() +
" items", Toast.LENGTH_SHORT).show();
mode.finish();
break;
default:
Toast.makeText(List16.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 = getListView().getCheckedItemCount();
switch (checkedCount) {
case 0:
mode.setSubtitle(null);
break;
case 1:
mode.setSubtitle("One item selected");
break;
default:
mode.setSubtitle("" + checkedCount + " items selected");
break;
}
}
}
}
Related
I Have a tablayout, within which in each tab, i have listviews that use custom adapters. I have setup the listview to Multi MODAL and defined a cabmenu. I have used the same cabmenu in another activity having similar tabs and listviews. I dont understand what i am missing , the cab menu is not appearing on long press on the listview items. The only difference between the other activity and this one is, the other has an action bar. Below is the code where the cab menu isnt working.
public void showLists(){
adapter=new CustomItemAdapter(getActivity(),listtype,fruititem,listid);
lv=(ListView) getView().findViewById(R.id.fruits);
lv.setAdapter(adapter);
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
lv.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
if (checked) {
selection.add(fruititem.get(position));
count++;
} else {
selection.remove(fruititem.get(position));
count--;
}
TextView tv = (TextView) getActivity().getLayoutInflater().inflate(R.layout.contextual_title, null);
tv.setText(count + " selected");
mode.setCustomView(tv);
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater menuinflater = new MenuInflater(getContext());
menuinflater.inflate(R.menu.cabmenu, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.deleteic) {
for (ItemLists s : selection) {
dbHandler.deleteItem(s);
}
adapter.notifyDataSetChanged();
mode.finish();
showLists();
}
mode.finish();
return true;
}#Override
public void onDestroyActionMode(ActionMode mode) {
count = 0;
selection.clear();
}
});
}
Am using CHOICE_MODE_MULTIPLE_MODAL for a ListView and it is working fine. problem is my ListView row item contains 2 buttons. And i want this all row buttons set to be disable when i have some rows checked.How to achieve this?
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
final int checkedCount = studentListView.getCheckedItemCount();
mode.setTitle(checkedCount + " selected");
adapter.toggleSelection(position);
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
SparseBooleanArray selected;
switch (item.getItemId())
{
case R.id.menu_item1:
mode.finish();
return true;
case R.id.menu_item2:
mode.finish();
return true;
case R.id.menu_item3:
mode.finish();
return true;
default:
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.multiselectmenu, menu);
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
adapter.removeSelection();
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
});
// Add one boolean in your model class and check same condition in adapter
raw_button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (<booleanvar==true>) {
//
}
}
});
Check when have some rows checked.
Call buton.setEnabled(false) for button you want to disable.
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)
So I've managed to create a context menu bar and it selects the colour of an item based on if it is checked or not.
It works fine for only 2 problems:
When the items are checked...further down in the list other items become checked as well, when they were never even selected (I am assuming it has to do with listview recycling on the getChildPosition)?
Also when my context menu bar closes...the highlighting stays and am not really sure how to remove it?
The solution: Remove the highlighting when the context menu bar closes and only highlight what I select to highlight.
Any ideas?
My Class:
listview = (ListView) findViewById(R.id.lst_contacts);
listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listview.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
try
{
final int checkedCount = listview.getCheckedItemCount();
mode.setTitle("Contacts: " + checkedCount);
if (checked)
{
count = count+1;
listview.getChildAt(position).setBackgroundColor(Color.parseColor("#6DCAEC"));
}
else
{
count = checkedCount;
listview.getChildAt(position).setBackgroundColor(Color.parseColor("#E7E8E9"));
}
}
catch (Exception e) {
e.printStackTrace();
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.contact_context_menu, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.delete_id:
Toast.makeText(getBaseContext(), count + " Contacts Deselected", Toast.LENGTH_SHORT).show();
count = 0;
mode.finish();
case R.id.save_id:
Toast.makeText(getBaseContext(), count + " Contacts Saved", Toast.LENGTH_SHORT).show();
count = 0;
mode.finish();
case R.id.load_id:
Toast.makeText(getBaseContext(), count + " Contacts Loaded", Toast.LENGTH_SHORT).show();
count = 0;
mode.finish();
}
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
});
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.