I have a custom ListView including a custom row_layout.
After a longclick you get different options from the contextmenu. Depending on what option is chosen by the user I want to add an image/icon to the selected row in order to mark it.
I couldnt find an answer which covers exactly this use-case. I would appreciate a hint or some help or a tutorial for this case.
Thanks in advance.
Never mind I got to a solution by myself. I added a boolean variable to my ListItem - Class and the ImageView to the list_row_layout as well as a ImageView to my ViewHolder Class within the CustomAdapter class. So when a contextItem is clicked the boolean Attribute is set to true for the listItem which was clicked on.
Example Code:
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int itemPosition = info.position;
switch (item.getItemId()) {
case R.id.contextItem1:
listViewItems.get(itemPosition).setMarkerAttribute(true);
listView.setAdapter(new MyCustomListAdapter(context, listViewItems));
return true;
case R.id.contextItem2:
//do sth
return true;
case R.id.contextItem3:
//do sth
return true;
default:
return super.onContextItemSelected(item);
}
}
Hope this was useful to somebody, because a lot of examples only cover removing an item ...
Related
I have a list of items.
I want to delete an item in a long push.
I saw this post and it worked for me.
just out of curiosity i wonder why other solution didn't work for me:
sol 1
I register the list to context menu:
registerForContextMenu(listView);
and then:
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
if (v.getId()==R.id.comments_list) {
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.phone_list_contextual_menu, menu);
}
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch(item.getItemId()) {
case R.id.edit: {
return true;
}
case R.id.delete: {
comments.remove(info.id);
listView.invalidate();
return true;
}
default: {
return super.onContextItemSelected(item);
}
}
}
Is there a difference between
listView.invalidate() and adapter.notifyDataHasChanged() ? beside the subject of the call?
what am I missing in order for the remove to work?
sol 2
listView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
int position = (int) v.getTag();
comments.remove(position);
listView.invalidate();
return true;
}
});
instead of
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
#Override
public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
comments.remove(pos);
//listView.invalidate();
arrayAdapter.notifyDataSetChanged();
return true;
}
});
I understand setOnItemLongClickListener is more suitable for my need than setOnLongClickListener but yet
why didn't this worked for me?
Is there a difference between
listView.invalidate() and adapter.notifyDataHasChanged() ? beside the subject of the call?
To my understanding adapter.notifyDataHasChanged() will do what listView.invalidate() plus more. That means it will also include change in number of items, and possibly inform other observers of data change. Relevant code is here:
http://androidxref.com/5.0.0_r2/xref/frameworks/base/core/java/android/widget/AdapterView.java#798
this is for notifyDataHasChanged(), as you can see mItemCount is udpated with new value. This means if you add more items to your arrayadapter, then invalidate, or better invalidateViews will not show them, at least at the end of list. One thing I have noticed is that above code has no invalidate call - maybe its called by some other methods.
Below is source code for invalidateViews (which is I think more proper than Invalidate):
http://androidxref.com/5.0.0_r2/xref/frameworks/base/core/java/android/widget/AbsListView.java#5078
It has no code to update count of item.
If you search source code for android sources, you will find only few cases when invalidateViews is called, some of those places are optimization hacks.
The difference is that invalidate causes all your views in the list to be scrapped and redrawn. Note I said views so that is what you are actually seeing on the screen (for example you can have 3 views on screen but 20 items in your list)
notifyDataHasChanged on the other hand tells the adapter that the contents have changed and the adapter needs to re-run its methods on the content to refresh the list.
You almost always want to use notifyDataHasChanged but it depends on exactly what you are trying to accomplish.
Hope that helps.
Im working on a simple music player for my intro to Android apps class. I want to be able to add songs to a playlist listed in my context menu. When I click on my addtoplaylist contextmenuitem I want my popup menu to appear. How do I call my popup menu? Also if you have some suggestions on how to populate my popup menu, rather than my for loop, that would be cool too.
I have a contextmenu listener that kind of looks like this.
#Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.share:
shareIt();
return true;
case R.id.Store:
musicStore();
return true;
case R.id.addtoplaylist:
// open popup menu
return true;
case R.id.snippet:
snippet(tem1);
return true;
default:
return super.onContextItemSelected(item);
}
}
And i have a popup menu that kind of looks like this.
public void showPopup(View v) {
int i = view.getPlaylists().size();
ArrayList<String> playlist = view.getPlaylists();
PopupMenu popup = new PopupMenu(this, v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.popup_menu, popup.getMenu());
for(int k = 0; k > i;k++){
popup.getMenu().add(playlist.get(k));
}
popup.show();
}
As you can see here PopupMenu
V is just an anchor, so you can pass for instance the ListView which contains your item
Or if you really want the popupmenu to be anchored to the item have a look here
You get your target view like this.
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
View v = info.targetView;
So after call
showPopUp(v);
For your loop, I don't see a far better solution.
the accepted question is fine, but for the for loop part you could use an iterator :)
for (String song : playlist) {
popup.getMenu().add(song);
}
Problem description: I wanted a "delete" function which could perform delete/remove of the selected entry in a listview and at the same time delete the residing video file string in the Video_List directory then it refresh the content of the listview?
I'm rather new in android/java can someone help me with it? Do scroll down to evaluate the problem i'm facing please!! Can someone tell me what is the specific code i should add into my current codes to perform the above mention function??
Since you have stored your selection into "item" object then in deleteFile() method you need to retreive the file path from that object, for that to work add the line:
model.absolutePath =
mfile.getAbsolutePath();
in getVideoFiles() method 'for' loop.
also before onCreate state:
ListViewAdapter lv;
then in getVideoFiles at the end state:
lv = new ListViewAdapter(this, R.layout.row, videoItems);
setListAdapter(lv);
finally in deleteFile() you need to state:
File myFile = new File(item.absolutePath);
lv.notifyDataSetChanged();
and that should work!
You defined an override onListItemClick but this code is never been called. You should also register the a listener to the view you're using. Check how android handle user interface events.
newListView.setOnItemClickListener(this);
Do you want to delete the adapter or do you want to delete a row/entry in the list? If latter, then update videoItems and call notifyDataSetChanged on your adapter. If you really want to delete the adapter, then just set it to NULL or have it refer to some other ListAdapter instance and the GC will take care of the rest.
#Override // create contextuel menu
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Action");
menu.add(0,100,1,"delete");
}
//////////////////////////////////////////////////
#Override // Select an item
public boolean onContextItemSelected(MenuItem item) {
final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch(item.getItemId()){
case 100:
public void onClick(DialogInterface dialog, int id) {
db.delete_item(info.id);
//here update list view
}
});
////////////
public boolean delete_item(long id){
return db.delete("name_table", "_id="+id, null)>0;}
////////////////
Problem description: I wanted a "delete" function which could perform delete/remove of the selected entry in a listview and at the same time delete the residing video file string in the Video_List directory then it refresh the content of the listview?
I'm rather new in android/java can someone help me with it? Do scroll down to evaluate the problem i'm facing please!! Can someone tell me what is the specific code i should add into my current codes to perform the above mention function??
Since you have stored your selection into "item" object then in deleteFile() method you need to retreive the file path from that object, for that to work add the line:
model.absolutePath =
mfile.getAbsolutePath();
in getVideoFiles() method 'for' loop.
also before onCreate state:
ListViewAdapter lv;
then in getVideoFiles at the end state:
lv = new ListViewAdapter(this, R.layout.row, videoItems);
setListAdapter(lv);
finally in deleteFile() you need to state:
File myFile = new File(item.absolutePath);
lv.notifyDataSetChanged();
and that should work!
You defined an override onListItemClick but this code is never been called. You should also register the a listener to the view you're using. Check how android handle user interface events.
newListView.setOnItemClickListener(this);
Do you want to delete the adapter or do you want to delete a row/entry in the list? If latter, then update videoItems and call notifyDataSetChanged on your adapter. If you really want to delete the adapter, then just set it to NULL or have it refer to some other ListAdapter instance and the GC will take care of the rest.
#Override // create contextuel menu
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Action");
menu.add(0,100,1,"delete");
}
//////////////////////////////////////////////////
#Override // Select an item
public boolean onContextItemSelected(MenuItem item) {
final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch(item.getItemId()){
case 100:
public void onClick(DialogInterface dialog, int id) {
db.delete_item(info.id);
//here update list view
}
});
////////////
public boolean delete_item(long id){
return db.delete("name_table", "_id="+id, null)>0;}
////////////////
Problem description: I wanted a "delete" function which could perform delete/remove of the selected entry in a listview and at the same time delete the residing video file string in the Video_List directory then it refresh the content of the listview?
I'm rather new in android/java can someone help me with it? Do scroll down to evaluate the problem i'm facing please!! Can someone tell me what is the specific code i should add into my current codes to perform the above mention function??
Since you have stored your selection into "item" object then in deleteFile() method you need to retreive the file path from that object, for that to work add the line:
model.absolutePath =
mfile.getAbsolutePath();
in getVideoFiles() method 'for' loop.
also before onCreate state:
ListViewAdapter lv;
then in getVideoFiles at the end state:
lv = new ListViewAdapter(this, R.layout.row, videoItems);
setListAdapter(lv);
finally in deleteFile() you need to state:
File myFile = new File(item.absolutePath);
lv.notifyDataSetChanged();
and that should work!
You defined an override onListItemClick but this code is never been called. You should also register the a listener to the view you're using. Check how android handle user interface events.
newListView.setOnItemClickListener(this);
Do you want to delete the adapter or do you want to delete a row/entry in the list? If latter, then update videoItems and call notifyDataSetChanged on your adapter. If you really want to delete the adapter, then just set it to NULL or have it refer to some other ListAdapter instance and the GC will take care of the rest.
#Override // create contextuel menu
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Action");
menu.add(0,100,1,"delete");
}
//////////////////////////////////////////////////
#Override // Select an item
public boolean onContextItemSelected(MenuItem item) {
final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch(item.getItemId()){
case 100:
public void onClick(DialogInterface dialog, int id) {
db.delete_item(info.id);
//here update list view
}
});
////////////
public boolean delete_item(long id){
return db.delete("name_table", "_id="+id, null)>0;}
////////////////