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)
Related
I have a ListView where I show a menu on the long click. In onContextItemSelected I have a logic to handle the action. I need to know what item in ListView is selected.
If a user selects item that isn't a submenu, I can use MenuItem.getMenuInfo().
But if a user selects a submenu, MenuItem.getMenuInfo() returns null.
What is the correct way how to determine the selected item if there's a submenu ?
The menu:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/Edit" android:title="Edit" />
<item android:id="#+id/Settings" android:title="Settings">
<menu>
<item android:id="#+id/V1" android:title="V1" />
...
</menu>
</item>
</menu>
onContextItemSelected:
#Override
public boolean onContextItemSelected(MenuItem Item) {
AdapterView.AdapterContextMenuInfo AdapterInfo = (AdapterView.AdapterContextMenuInfo)Item.getMenuInfo(); // getMenuInfo returns null if V1 is selected (submenu) but works if selected item isn't submenu, e.g., 'Edit' as per above XML
UserItem SelectedItem = MyAdapter.getItem(AdapterInfo.position); // MyAdapter is the instance of class that inherits from ArrayAdapter<UserItem> i.e. adapter for ListView
}
you need to do 3 things
1.provide a default section in your switch statement that handles your menu items
2.save off the info.position to a member variable in your Activity
3.when you detect that info is null, use the var you created in step 2
private int mParentContextMenuListIndex;
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info;
try {
info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
} catch (ClassCastException e) {
Log.e(TAG, "bad menuInfo", e);
return false;
}
//if info == null, it means we have a submenu to deal with, use the saved info.position
int idxOfList = (info!=null) ? info.position : this.mParentContextMenuListIndex;
...
switch (item.getItemId()) {
case R.id.context_menu_item_1:
... //use idxOfList instead of info.position
return true;
case R.id.context_menu_item_2:
... //use idxOfList instead of info.position
return true;
case R.id.context_menu_item_3:
... //use idxOfList instead of info.position
return true;
case R.id.context_submenu_item_1:
... //use idxOfList instead of info.position
return true;
case R.id.context_submenu_item_2:
... //use idxOfList instead of info.position
return true;
default: //can handle submenus if we save off info.position
this.mParentContextMenuListIndex = idxOfList;
}//switch
return super.onContextItemSelected(item);
}
Why don't you use onItemClickLitener() for all the items in you listview without dividing them on munu items and submenu items?
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String s = listView.getItemAtPosition(i).toString();
}
});
So i will be your item position.
If you still want to work with submenu items you need to implement onOptionsItemSelected(MenuItem item) method and catch onclick events based on the id of submenu items .
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case 10:
//do smth here
return true;
case 15:
//do smth here
return true;
case 20:
//do smth here
return true;
default:
return super.onOptionsItemSelected(item);
}
}
I have problems with implementing a dropdown (like a spinner) list in my customized ActionBar. I've tried several solutions, including getActionView() but it doesn't work :/
Here is my code; #Override public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.planner_menu, menu);
MenuItem category_item = menu.findItem(R.id.CategoryAppointment);
Spinner spinner =(Spinner) category_item.getActionView();
String[] categories = new String[]{"meeting","training","puls","medicin","bloodsample"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item,categories);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
parent.setSelection(position);
switch (position) {
case 0:
String category = parent.getSelectedItem().toString();
Toast.makeText(parent.getContext(),
"OnItemSelectedListener : " + category, Toast.LENGTH_SHORT).show();
// Take string and compare it in database.
DB.getAllAppointmentsByCategory(category);
break;
case 1:
// Take string and compare it in database.
break;
case 2:
// Take string and compare it in database.
break;
case 3:
// Take string and compare it in database.
break;
case 4:
// Take string and compare it in database.
break;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
for (int j = 0; j < menu.size(); j++) {
MenuItem item = menu.getItem(j);
Log.d("TAG", "set flag for " + item.getTitle());
item.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
return true;}
And here is the the options from the meny.
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()){
case R.id.AllAppointments:
//DB.getUsersAppointment();
return true;
case R.id.WeekAppointment:
//DB.getUsersAppointmentByWeek(date);
return true;
case R.id.CategoryAppointment:
// setupSpinner();
//DB.getUsersAppointmentByCategory(category);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
The code from the XML file.
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" tools:context=".Planning">
<item android:id="#+id/AllAppointments" android:title="All"
android:orderInCategory="10"
app:showAsAction="always|withText">
</item>
<item android:id="#+id/WeekAppointment"
android:title="Week"
android:orderInCategory="10"
app:showAsAction="always|withText"
>
</item>
<item android:id="#+id/CategoryAppointment"
android:title="Cathegories"
android:orderInCategory="10"
app:showAsAction="always|withText"
>
</item>
`
In item id -> CategoryAppointment I want to show a dropdown meny where the user can choose between diffent categories and then list out the data from the database.
I've been working with this for the past hours but I can't seem to fix it. Can someone please explain to me what I have to do and what it is that i'm doing wrong here.
Thank you.
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.
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;
}
}
}
}