Calling notifyDataSetChanged reversing the position's order, is this a bug? - android

I'm developing one android application in which I'm using one customized ListView which extends BaseAdapter, In which I have placed two TextView's and one button to delete the corresponding row from the list and also from the original data,
Whenever I call the notifyDataSetChanged() function the value of the position get reversed, am I doing anything wrong ?, Is there any other correct way to do this without the position get reversed ?
convertView.setOnClickListener(new OnClickListener() {
private int pos = position;
public void onClick(View v) {
Toast.makeText(context, "Click-" + String.valueOf(pos), Toast.LENGTH_SHORT).show();
}
});
holder.delete.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
adapter.notifyDataSetChanged();
}
});
Any help will be appreciated.

Instead of on click for button in the every row in the list I just used context menu and performed the actions needed and updated the list and now its working.
Actually this is not the solution for my question and its just an alternative.

Related

Get the listItem ID in a onClick method of SetOnClickListener method of an adapter?

I have an activity which lists objects from an array objects through a custom adapter. The row of this adapter contains several EditText's and a layout which is clickable and does the deleting of that object selected. My intention is the object can be updated by clicking on the item (which shows another activity) and deleting by clicking on the layout. So that, I have to implement the updating and the deleting by differents setOnItemClickListener's.
I have done the updating just setting an setOnItemClickListener to the listView of objects and sending the whole object to a new activity through putExtra and getIntent.
The problem is with the deleting. I have implemented an OnClickListener directly on the adapter, like this:
holder.layoutEliminar.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Here call to an Async Task to delete the object but, what about t the id object???
}
That code goes fine when I click on the layout of the row but I don't know the way to obtain the id of the object selected in the listView. Does anybody know how??
Do not hesitate to ask me for more code or details.
Please excuse my English, not native.
You can set a tag for the view on your getView:
holder.layoutEliminar.setTag(theIdOfYourObject);
Note that View.setTag(Object tag) takes an Object as parameter (documentation). I will assume that you want to set the id of the object to delete as String for the tag.
And then, on your onClick
holder.layoutEliminar.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
LinearLayout layoutEliminar;
// Retrieve your layoutEliminar from v
// ...
// Get the id of the object to delete from the tag
String id = (String) layoutEliminar.getTag();
}
};
I already did with the help of #Antonio. I didn't use Tag's, I have used the instruction getItem(position).getId() into the method onClick to refer the id of the object (don't know if it's the best and more efficient way to do). Like this:
holder.btnEliminar.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.i("PedidosAdapter dd: ",String.valueOf(getItem(position).getId()));
//Async Task for deleting the object with that ID
}
});

Android button on card view, get position of card view on click

I've got a card-view that each card has a button on it. I'm trying to get the position of the card that holds the button when the users clicks the button.
I have an adapter that extends from RecyclerView.Adapter and implements the following method...
public void onBindViewHolder(MovieImageViewHolder movieImageViewHolder, int i) {
Movie movieItem = mMovieList.get(i);
movieImageViewHolder.details.setTag(i);
movieImageViewHolder.details.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
position = (Integer) v.getTag();
}
});
}
This works sucessfully, when I press a button on card 1, position equals 1 and when I press a button on card 4, position equals 4.
The question is, how do I get this value (position) out of the adapter and back into the Activity so I can use it? or do I even need to do that? I'm trying to create a new intent but don't think that should be done from the adapter?
I attempted to create a getter for the variable position, and call the primary button action with
public void buttonClick(View view) {
int position = adapter.getPosition();
Log.d(TAG, "Button Clicked::- " + String.valueOf(position));
}
Using
android:onClick="buttonClick"
In the XML, but nothing happens when clicking the button, I believe this is because the OnClick method in the adapter is fired instead?
EDIT:
Seems I've made some progress. Worked out that I can set the tag in the adapter
movieImageViewHolder.btn_details.setTag(i);
Then get that tag back in my onClick method with .getTag();
Only thing now is the tag seems to be zero for the first element, then zero for the second element, then starts at one for the third... Any reason why this would be?
This was actually very simple and a very common "issue" people face. I was set down the path that I couldn't create an activity from an adapter where infact that is exactly what I should have been trying to do.
movieImageViewHolder.details.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
Integer taggedPosition = (Integer) v.getTag();
Intent intent = new Intent(mContext, ViewMovieDetailsActivity.class);
intent.putExtra(SearchMovie.MOVIE_TRANSFER, getMovie(taggedPosition));
v.getContext().startActivity(intent);
}
});
Correctly starts the correct activity.

Deleting an item in a list view

I am using a custom list view by extending the ArrayAdapter class. Each row has some text as well as an image. What I want to do is delete the row when I click on the imagevView. So i set an onclick listener as well as a tag for each image view and then used the onclick listener to change the adapter. However it simply refuses to work. What exactly am I doing wrong?
holder.image.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view)
{
Toast.makeText(context, "ImageView clicked for the row = "+view.getTag().toString(), Toast.LENGTH_SHORT).show();
createEvent.list.remove(view.getTag());
createEvent.adapter.notifyDataSetChanged();
}
The toast prints correctly. However the item is not deleted. Any ideas on how I can achieve this?

Delete an item from the listview and refresh it on a button click in each row

Hi a am struggling with this part. I want to simply delete an item from the listview when the button on that row is clicked.
I have tried
holder.button.setText("End");
holder.button.setTag(position);
holder.button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Integer index = (Integer) v.getTag();
app_details.remove(index.intValue());
notifyDataSetInvalidated();
}
});
But it's behavior is unpredictable I mean when click on the button on a row it delete the another item from the listview.
Any one have some idea?
Thanks
I have faced the same problem & finally get rid out of it. Have to tried
holder.button.setOnItemClickListener Follow the steps to do what you want:
Implement OnItemClickListener in your current activity class.
set button which delete item from list view to setOnClickListener.
Set list view to setOnItemClickListener listener in your anonymous inner class (e.g., in OnClickListener).
notifyDataSetChanged()
Call this Activity once again Using Intent.
here for Example: I take one list view listVw ->
holder.button.setText("End");
holder.button.setTag(position);
holder.button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// your needed stuffs...
listView.setOnItemClickListener(this);
}
});
#Override
public void onItemClick(AdapterView arg0, View arg1, int position, long id) {
// TODO Auto-generated method stub
//Do your stuff here...
}
You want to uses an instance of the ArrayAdapter since that adapter has the remove method. Otherwise you will need to implement your own remove method and have you custom Adapter extend BaseAdapter. Here is an example of what methods you need to call to remove an item from the list and tell the Adapter to refresh the list.
m_adapter.remove(o);
m_adapter.notifyDataSetChanged();
You want to call notifyDataSetChanged() instead of notifyDataSetInvalidated(). Here is the difference ....
notifyDataSetChanged() - Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.
notifyDataSetInvalidated() - Notifies the attached observers that the underlying data is no longer valid or available.

android: onClick responds only to second click in listview

I found a similar question about scrolling listview and button click but it did not help me. My issue is:
I have a listview with custom rows. I have two different states of listview; the switch between the states is a button at the bottom of the screen. The second state has delete buttons in every row. When I click on delete button in a specific row, that row is removed from database and listview is updated. Everything works great except I need to click the delete button twice in order for it to work. Below is my code for handling the clicks. flag==1 is the second state of the listview.
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
View main = parent.getChildAt(position);
TextView delete = (TextView)main.findViewById(R.id.delete_button);
if(flag==0){
switchToItemsView(id);
}
if(flag==1){
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mDbHelper.deleteList(id);
updateListView();
}});
}
}
I tried to set parent view's focusableInTouchMode attribute to false as suggested in another post but it did not help.
If you can help me solve this I will be grateful,
Thank you in advance.
Probably you have focus. Remove it.
android:focusableInTouchMode="true"
android:focusable="true"
You need to declare the onClickListener before the actual flag check; in your case the view changes and with that the flag, and the listener is set. The next click actually triggers the listener.
Not related, but you should change your second if to an elseif since there is no way it would be called if the first one is called.
After spending hours I figured out how to do it:
I moved my click listener from my main activity class to my custom ListAdapter class and modified it a little like below;
deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int rowid = Integer.parseInt(rowIds.get(position));
mDb.deleteList(rowid);
lists.remove(position);
notifyDataSetChanged();
}
});
Now it works great. When I click delete button it removes the list both from the ArrayList (the one used in ListAdapter) and from database.

Categories

Resources