I am trying to delete an item in my listview through a context menu. I have the context menu working and I can easily insert new items to the list view but I can not remove them. I have two options edit and delete.
public boolean onContextItemSelected (MenuItem item)
{
super.onContextItemSelected(item);
if(item.getTitle() == "Edit")
{
Toast.makeText(this, "Edit", Toast.LENGTH_LONG).show();
}
if(item.getTitle() == "Delete")
{
Toast.makeText(this, "Delete", Toast.LENGTH_LONG).show();
myActivities.remove(item.getGroupId());
populateListView();
}
return true;
}
for some reason, the item being deleted is always the first item!
myActivities is my dynamic array and all I do in populateListView is populate it. I know populateListView works since if I add an item to myActivities then use the function, the new item will be added. Delete is not working though!
Note: I have also tried
myActivities.remove(item.getItemId());
Let me tell you the general approach for deleting item from Listview.
You have a list of data, which you pass to the adapter and through adapter display in Listview to the user.
So when you want to delete a particular item, first get the position of the item, delete it from the datalist. As the underlying data has been changed call notifyDataSetChanged() on the adapter which will make the Listview to refresh the child views.
Try following:
if((item.getTitle()).equals("Delete")) // You are comparing Strings, don't use ==
{
Toast.makeText(this, "Delete", Toast.LENGTH_LONG).show();
removeItemFromList(itemPosition);
}
// method to remove list item
protected void removeItemFromList(int deletePosition) {
your_datalist.remove(deletePosition);
adapter.notifyDataSetChanged();
}
Hope it helps.
Related
I have a RecyclerView to list a set of data. And on clicking each item , I have validation to check previous item is entered or not. If that item is not entered I want to enable an inline error (which is hidden in normal case) message in the previous row. I have done the scenario as shown below but error is showing only in the current row. Anyone suggest how I can enable/update previous row or a specific row.
public boolean _validateListItems(int itemIndex)
{
int previousItemIndex = itemIndex - 1;
for (int i = 0; i <= previousItemIndex; i++)
{
if ((listRecyclerItem.get(i).getEnable()==0))
{
return false;
}
}
return true;
}
holder.expand_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(position>0){
if(_validateListItems(position))
{
mExpandedPosition = isExpanded ? -1:position;
notifyItemChanged(previousExpandedPosition);
notifyItemChanged(position);
notifyDataSetChanged();
}
else
{
holder.error.setVisibility(View.VISIBLE);
holder.error.setTextColor(ContextCompat.getColor(context, R.color.error_red));
}
}
}
});
First of all RecyclerView is something that recycle view. View is generated is based on Data Model.
So, lets store the user button/checkbox click/checked action) to the respective Model/Item. To run the validation, get the items from the Adapter and check your conditions in Activity/Fragment [Looping is an expensive operation, use Coroutine or RxJava]. Execute your validation and if Validation is true for an item, just update the Item from the list and finally update the Adapter. You can pass the Error message in the item and render it to the View. And finally, must use DiffUtil to update the items in adapter.
Declare an interface for your adapter that has callback to your viewModel and when each item changed you can return the call back ito viewmodel and store it in an object or array
for example :
interface Callback { void onDataChanged(int itemPosition); }
call that method in onBindViewHolder when your item text changed
and in view model add the returned item into a list
when you clicked on a button, you can check the items if your necessary item didn't exist you can return error
I have a one ImageView (With border heart icon) in each row of my
recyclerview. I use this icon for add to favorite list . when I press this
image view it's change to other icon (complete heart icon) . every thing is ok
, But when i go to other
Activity it return to the default icon (border heart icon) . I use the flag for doing this work .
This is my RecyclerView Adapter (image onClick event):
//============== IMG ADD TO FAVORITE CLICK LISTENER ======================
holder.imgAddFav.setOnClickListener(new View.OnClickListener() {
boolean flag = false;
#Override
public void onClick(View v) {
QuestionDatabaseAdapter databaseAdapter = new QuestionDatabaseAdapter(v.getContext());
if (!flag) {
ModelQuestion question = new ModelQuestion();
question.setQuestionTitle(questionha.get(position).getQuestionTitle());
question.setQuestionDesc(questionha.get(position).getQuestionDesc());
question.setQuestionDate(questionha.get(position).getQuestionDate());
question.setQuestionAuthorName(questionha.get(position).getQuestionAuthorName());
question.setQuestionAuthorPic(questionha.get(position).getQuestionAuthorPic());
question.setQuestionDownLink(questionha.get(position).getQuestionDownLink());
databaseAdapter.saveQuestion(question);
Toast.makeText(v.getContext(), "Added !", Toast.LENGTH_SHORT).show();
holder.imgAddFav.setImageResource(R.drawable.ic_favorite_red_700_24dp);
flag = true;
} else {
Toast.makeText(v.getContext(), "Removed !", Toast.LENGTH_SHORT).show();
holder.imgAddFav.setImageResource(R.drawable.ic_favorite_border_red_a700_24dp);
flag = false;
}
}
});
}
And this is my icons .
To maintain the state of your each item, in your model class create a boolean for ex:"isClicked", by default make it false, when he clicks make it true in adapter onclick, u need to display item based on this "isClicked" property.
if(isClicked){
//show filled heart
}else{
//show empty heart
}
It will return to default icon at holder.imageView.setImageResource();
To over come this store the items added to favourite list and then set the image properly.
//this is a simple code to check whether its in favourite
//itemMap is a static HashMap<Integer,Boolean>
// make a statement like isFavorite=itemMap !=null && itemMap.get(new Integer(position) to be used in if else statement
//use the hashmap for current use. If hasgmap is null retrieve it from a database.
//you should probably do that at the constructor of the adapter
if(isInFavourites){
holder.imageView.setImageResource(R.drawable.favouriteImage);
}else{
holder.imageView.setImageResource(R.drawable.addFavImage);
}
Its always good practice to store the favourite item at onClick in a hash map and in a database using a new thread to prevent a possible lag.
Explanation as requested
You have a onBIndViewHolder() method in your recycle view adapter and it contains the method holder.imgAddFav.setImageResource() which you use to add the favourite border image.
The adapter calls that function whenever the recycle view items are created and the bordered image is set as a result.
So at imgAddFav onClick you save the newly added item to favorites in a static hashMap that you've declared as an instance variable.
//consider the hashMap as favMap;
HashMap<Integer,Boolean> favMap;
//at the constructor of the recylcer view you've to check whether you have items that you previously added to the favorite list
public YourAdapter(/*parameters*/){
if(favMap==null){
favMap=new HashMap<>();
}
//now fill the map with stored data
//You can use sharedpreferences or a datase
//for an example think that postio 2 is in favorites;
favMap.put(new Integer(2),true);
}
Now back to the getItemHolder(). Here before setting the imgAddFav image check from the hashmap whether the particular position is in favourites.
//set a boolean to check whether this item is in favorites
boolean isInFavorites;
if(favMap.contains(new Integer(position)) && favMap.get(new Integer(position){
//the item is in the favourite list
//set the full colored image
holder.imgAddFav.setImageResource(R.id.coloredHeart);
isInFavorites=true;
}else{
holder.imgAddFav.setImageResource(R.id.borderedHeart);
isInFavorites=false;
}
Now at onclick not only change the image but store the result as well
holder.imgAddFav.setOnClickListener(new View.OnClickListener{
#Overrride
public void onClick(View v){
if(isInFavorites){
favMap.put(new Integer(position),false);
//save this same thing in a database or sharedPreference.Do it in a new thread.
//if you want to save to a database
new Thread(new Runnable{
#Override
public void run(){
//insert into database
}
}).start();
//or else if you want save to sharedPreference you can use edit.apply() method
//now change the image or simply call notify datasetChanged
notifyDatasetChanged();
}
}
});
I have approx 150 items in my custom listview. I am trying to implement the following:
list.setOnItemClickListener(new OnItemClickListener()
{
1. I get position of the item
2. Get the data from an ArrayList
3. Add the data to database.
This part is working fine.
But if I want to remove a particular item from the database by clicking on the item I am not able to achieve this part?
Reason because I am not sure if the item is clicked or not? I have this problem mainly when I want to implement search in the listView and add the selected item to database and remove selected item from database.
// Click event for single list row
list.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
if (notfromsearch == true)
{
String profile_ID = profileList.get(position).get(KEY_ID);
String profile_DISPLAY_NAME = profileList.get(position).get(KEY_DISPLAY_NAME);
//add to database now
}
elseif (notfromsearch == false)
{
String SearchResult_profile_ID = searchProfileResults.get(position).get(KEY_ID);
String SearchRResult_profile_DISPLAY_NAME = searchProfileResults.get(position).get(KEY_DISPLAY_NAME);
//add to database now
}
}
});
But how to implement remove from database? I am not able to differentiate if the item is clicked before or not to remove from database.
Can somebody help me out with this?
Thanks!
On your list view, use
setOnItemClickListener
and you can do what you want next .
use context menu for deleting items from the database
on long press display delete/edit option and perform further operation as needed.
check here for context menu sample
EDIT
You can also put button/image in the listview to delete item and then implement your delete operation in the click method.
For Checkbox selection
model class
class CustomClass
{
boolean checked;
//other fields
}
in your custom adapter class
ArrayList<CustomClass> data = new ArrayList<CustomClass>();
and in getView() method
checkboxItem.setChecked(data.get(position).getChecked());
and don't forget to change the checked boolean value on checkbox change listener..
I am working with a ListView trying to add/delete items. The addition bit was fairly easy, the removing though is proving to be trickier.
I was thinking to use a multiple choice list, but to start with something simpler I chose a single choice mode just to test it out.
I have an array of strings containing the items, an array adapter to notify when Data has changed.
expenseAdapter=new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_single_choice,
android.R.id.text1,
expenseList);
myListView.setAdapter(expenseAdapter);
myListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View item, int position,
long index) {
((ListView)parent).setItemChecked(position, true);
item.setSelected(true);
}
});
I have also added a listener for the item onClick Event. Visually the item gets selected/deselected the issue is when I click the button which triggers the deletion of the item the selected index in the list is always -1 although the item appears to be selected.
Delete button with onClick event
public boolean doDelete(View view)
{
ListView myListView= (ListView)findViewById(R.id.list);
String s=(String)myListView.getSelectedItem();
expenseList.remove(s);
expenseAdapter.notifyDataSetChanged();
return true;
}
Any ideas what is happening or what I'm doing wrong?
use this
xmlfile : https://www.dropbox.com/s/eky9zb275mgt4py/activity_list__addand_delete.xml
javaFile : https://www.dropbox.com/s/idqyyosbutgqqbs/List_AddandDelete.java
your selection ( focus ) is removed when ever you will shift your focus to button .
I have seen your code and understand that problem, you are getting -1 index when you are removing item from List because that item is not existing in that list so change your code please try this.
I changed getSelectedItem() to getSelectedItemId() here it will return selected item id instead of Item so you can remove that item from List based on item id which will be the Index of item in List.
public boolean doDelete(View view)
{
ListView myListView= (ListView)findViewById(R.id.list);
long id = myListView.getSelectedItemId();
expenseList.remove(id);
expenseAdapter.notifyDataSetChanged();
return true;
}
Hope it will help you.
I am using a custom list view in my application. In custom list view in all rows I have placed an image button. If I click that image button, I have to delete clicked button row in the custom list view. Can anybody tell me how to do this? The below coding is not working:
imgcross=(ImageView)v.findViewById(R.id.imgcross);
imgcross.setId(position);
if(v.getId()==R.id.imgcross)
{
Log.d("image id is",Integer.toString(imgcross.getId()));
myScheduleList.removeViewAt(imgcross.getId());
Toast.makeText(MyScheduleDay0RequestedMeeting.this, "Cross Button is Clicked", Toast.LENGTH_LONG).show();
}
if (v.getId()==R.id.imgcross)
{ //Integer index=(Integer)imgcross.getTag();
//Log.d("image id is",Integer.toString(index));
int index=imgcross.getId(); (imgcross.getId());
MyScheduleBean.listName.remove(index);
MyScheduleBean.dateValue.remove(index);
MyScheduleBean.dateValue.remove(index);
CAdapter = new CustomAdapter(this,MyScheduleBean.listName,MyScheduleBean.dateValue,MyScheduleBean.meeting,R.layout.myschedule_day0_requestedmeetingrow,to);
myScheduleList.setAdapter(CAdapter);
}
Thanks
You need to delete the data from the underlying Adapter. Done properly, this will automatically update the ListView. Otherwise, also call notifyDataSetChanged() on the Adapter, and that will cause the ListView to update.
I've been searching too long for this answer - thank you very much.
After deleting the record from the database with:
DBRecordOperation.deleteRecord(dbRecord);
simply remove the record from the ListView with:
adapter.remove(dbRecord);
I'm doing this on a long click in the ListView. Full code for onContextItemSelected is:
#Override
public boolean onContextItemSelected(MenuItem item){
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
DBRecord dbRecord = (DBRecord) getListAdapter().getItem(info.position);
int dbRecordId = dbRecord.getId();
DBRecordOperation.deleteRecord(dbRecord);
adapter.remove(dbRecord);
return true;
}