I added a button in a listview item, and after the button is clicked, I want the button is disabled. I used the below setOnClickListener for my button in the custom adapter, but the problem is when i clicked on a button, the button of another list item will also be disabled. For example, when I clicked the button of item 1, the button of item 1 then is disabled, but the item 4's button will also be disabled at the same time although i didn't click on it.
And also, when I scroll up and down, all item's button just enable and disable randomly.
Anyone know why is this happening?
holder.viewBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.viewBtn.setEnabled(false);
showInfo();
} });
I was so frustrated when I first faced this problem!
The problem here is that the listview just doesn't remember the state of the button. Dunno if it is a bug but anyways I needed a way out and this is what I did.
I believe you are using a custom adapter with a viewholder. Means you are on the right path. You need to keep an array of booleans whose size is equal to the number of items in your list. in your btnClick() set the state of the item in the array.
Now everytime you scroll, or do soemthing that makes the list redraw, getView() is called. Put a check in your getView() for the items state and enable/disable it. One more thing, Make sure you implement both if{} and else{} for the check.
if(checked){
holder.viewBtn.setEnabled(false);
}else{
holder.viewBtn.setEnabled(true);
}
if you don't do this you'll see weird behaviours. One more thing if you are using the
if(convertview == null){
//create the holder
}else{
convertview = getTag();
}
method, make sure you populate the state after the above step.
I have not seen your implementation but I had to pop up a button in the item and then delete the item from the list using it. So I had to take extra care for maintaining the state.
So be careful about the states once the underlying data has changed.
Sorry about the long post but the problem is such :(
I found a link that has the solution in a basic format
This is happening because ListView reuses Views in an erroneous manner. Either implement your own ListAdapter without View reuse or file a bug report with Google
Related
I have 3 activities containing listviews with custom adapters, an item selected at the first one drives the user to the second one, and so on...
At these listviews, some items are highlighted as "new itens" (each time adapter's getView is called, I check at a database if the current item should be highlighted). Once user has reached the 3rd listview, I mark these items as "checked", and want to propagate this change back to the other listviews...
That means, when user comes back, pulling the 2nd and 1st listviews up from the stack, I want the viewed items not to be highlighted anymore.
I've tried this answer on SO, without success. When executing notifyDataSetChanged() from onResume(), my listview simply didn't shows up. And I'd prefer not to use startActivityforResult()...
here's my code to refresh the listview at onResume():
#Override
public void onResume(){
super.onResume();
//I have basically the same code at onCreate()
adapter = new ListingsAdapter(getApplicationContext(), this);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
here's another answer that sounds promising, but I wasn't sure how can I retrieve an specific view from the adapter... I want to check all visible items with adapter.getView(), but it asks for a convertView and a parent ViewGroup and I couldn't get that
Thanks in advance for any hint on this
Why don't you wanna use startActivityforResult()?
You don't need to create a new adapter every time in onResume(). You only need to change the underlying data (set the checked flag for the visited item) and then call adapter.notifyDataSetChanged(). This will trigger the adapters getView() method for all the visible list elements.
I want my ListView to work something like the following:
When I press a button (probably from context-menu), I want the user to be able to select more then one item from ListView (probably using check-boxes), but those check-boxes should not be visible before that.
So, the point is, after the user presses a button (let's say "Delete more items"), the listview, should update itself, and appear on every row of the list, a checkbox should appear (allowing me to select the items ID to pass those to server).
How can I achieve that, without having to recreate the list from zero? (how to setVisibility ON, keeping the other content of the ListView as it is, and not doing another request to server).
PS. If you guys, have another better idea, on achieving the Delete More Items, would be much appreciated!
This is just an idea, haven't tried it myself: you build in a checkbox in your listitem layout. Normally, in the getView of your adapter, you set it invisible with
checkBox.setVisibility(8);
When you want to show them, you set some boolean
showBoxes
of your adapter to true, then in the getView oyu don't hide the checkboxes.
Then
notifyDataSetChanged
on the adapter.
Hope it's clear what I mean.
In my android app, I have a listview with an option to delete items from it
on the same screen. The delete button lies at the bottom of the list view
and there's a function written for deleting items and refreshing the list view.
This function is being called in onClick() of the List View.
This is where the problem lies.
In delete button's onClick I have first made a check for knowing which item to delete -
if (ListView.INVALID_POSITION != mListView.getSelectedItemPosition()) {
//delete the selected item
}else{
//do nothing
}
So whenever user touches delete button the focus from list view is removed and we get invalid as the list view position and hence the item is not deleted.
I also tried to store the value of selected item in a constant and update it in list view's onItemSelected() method and then remove the condition from Delete Button's onClick
.This works but causes another problem - If the user taps into empty area then focus from list view is removed and it appears that nothing is selected, but if u press delete button and then it deletes the last selected item as it is coming from a constant.
This is the problem I am facing.
Please suggest what to do.
Selection is useful only in keyboard mode, its turned off in touch mode so, getSelectedItemPosition() is not always reliable.
Read do's and don't in this developer blog entry.
If you want to use a single button, Set ListView choice mode to Single/Mutliple, then, on button click, get the checked items and delete them, refresh ListView after that.
Try to implement the onitemclickListener() and get the item id and delete the item clicked in the arrayadapter by implementing the onclick() for the button and next call adapter.notifyDataSetChanged();
I have seen plenty of samples which support a checkbox for each item in a list but this seems to be about as far as they go. My problem is that I have two lists of items which interact.
The first list displays Method Statements - when the user select a method statement the second list displays a list of Risk Assesments for this method statement. I have this all working with no issues.
I now need to extend this so that the user can select (via a checkbox) the Method Statements that they want to use. What this means is that I do not want the selection of the listitem to set or clear the check box, just populate the second listbox. I do however need the user to be able to manually check the item to include it.
Any suggestions please would be most welcome - maybe a ListView is not the correct way to do this, perhaps a dynamically created table within a scroll view?
I would try this way.
Set choice mode of ListView as NONE.
Build a ViewGroup (Linear/Relative/Frame Layout) with TextView and CheckBox. It will
be a cell of ListView.
When you bind view in the adapter, set CompoundButton.OnCheckedChangeListener on the CheckBox. Place position of your view in the Integer and set it as a tag for your cell (remember: do it in the binding data with view).
private static class MyOnCheckedChangeListener implements CompoundButton.OnCheckedChangeListener {
#Override
public void onCheckedChange(...) {
Integer position = (Integer) view.getTag();
//your logic with position
}
}
Or just set OnClickListener.
The idea is: let CheckBox be clickable and let it consume click events - then its parent will not receive this events and AdapterView.OnItemClickListener will not be fired.
As the title say.. Are the ListView equipped of some system to enable clicked item to stay selected ?
Thanks.
Besides, focus there is no such thing. You can improvise it by setting color to the item.
Unfortunately not.
Here is an answer previously provided:
Highlight ListView selected row
Because of the way the Android Framework is designed with Touch Mode, there is no way to do so without creating a custom ListView and programatically setting the background to a different color. You can keep track of your "last selected view" either through an id, a position, or a reference to the view itself.
Another option is to do this in a custom adapter's bind view, although this is more of a hassle because all your views have to be rebuilt in order for it to work properly.
I have read somewhere that they are to fix this issue in the Honeycomb though.
Sorry guys but i found a way to do so and it work fine. It was exactly what i was looking for. To help others i will post an exemple.
First, you have to implement the mode in the layout with android:choiceMode="singleChoice".
You need to specify a multi-choice list in the adapter.
ArrayAdapter adapter = new ArrayAdapter(monContext,
android.R.layout.simple_list_item_single_choice, maListePrenoms);
3.Then in the code you can get the value of the selected item...
btnAfficherNom.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
Toast.makeText(monContext, lstPersonnes.getItemAtPosition(lstPersonnes.getCheckedItemPosition()).toString(), Toast.LENGTH_SHORT).show();
}
});