The problem I hope to resolve here is that when I click on one item in the ListView that item's background changes to light gray, but when I continue to scroll through the list every 4th item has the background changed to light gray even though those other items have not been clicked. How do I make only the item I clicked be effected by the click?
ListView lv = (ListView) findViewById(R.id.resultsList);
lv.setAdapter(new ArrayAdapter<String>(this, R.layout.resultitem, (String[])labelList.toArray(new String[labelList.size()])));
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView tv = (TextView)view.findViewById(R.id.result);
tv.setBackgroundColor(Color.LTGRAY);
tv.setTextColor(Color.BLACK);
}
}
You'll have to override getView() in a subclass of ListAdapter, in this case, ArrayAdapter.
This is because Android actually reuses rows to conserve resources and CPU (when a row is scrolled off the screen, it is reused for new rows that come into view). So, if you set the background grey on one row, it'll probably end up being used again, and the background will still be grey.
If you subclass ArrayAdapter, you can have your onItemClickListener set some sort of flag, and then your ArrayAdapter's getView(), you can set the appropriate background color based on the flag.
This link has an example of subclassing ArrayAdapter
I suppose you are using convert view just like this
...public View getView(int position, View convertView, ViewGroup parent) { ....
and you are changing its background at 4th position, and your view let says have 6 rows on one page, so every 4th row of every page will be grayed out because of reusing the same convertView .
I don't know that I am explaining right, but if you are using convertview and changing its layout, so you should have logic to re-create that layout again to avoid re-using same (cached) view.
Related
I have an expandable list view with checkboxes. When i click a child, an alertdialog and i choose the quantity and then the textView of a child changes. BUT when i scroll down the list and this child disappers from view , the list forget changed textview and set the old one. What's the reason?
ListView (and its descendent ExpandableListView) does NOT create and store the views forever; instead it creates them on-the-fly as needed.
Imagine a scenario where you have a ListView with a list containing 1000 items; but the views for only any 5 items can be visible on the screen at a given time. Do you think that ListView would create and maintain 1000 different views on the screen? That would be a waste of memory, and might cause the UI to lag.
Instead, ListView internally calls getView() function to obtain the view for each item and shows it on the screen. It does this every time the item is brought into the screen display, and only for those many number of items which can fit into the screen at a given time (ListView handles these things internally so you do not have to worry about this)
All you need to do is set the text in the corresponding list item, and use this text to populate the textview in getView(). Maintain a text String and create some form of getText() and setText(String) methods in whatever Object type you are using as an Item.
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
......//initialize text view for this position
Item item = getItem(position);
textView.setText(item.getText());
.......
}
Once you set the text in the list item via alertDialog, Call notifyDataSetChanged() on the adapter to indicate that getView needs to be called again for all the views currently in display.
In your Listener, pass a reference to the adapter of the ListView. When you set the quantity in the alertDialog, just use
{
......
adapter.getItem(position).setText(quantityText);
adapter.notifyDataSetChanged();
......
}
The first line sets the text in the item; the second line tells the adapter that the information in the items have changed and it needs to create the views again.
I am using horizontal list view and adding dynamic data into this, but I want to add an item when the scroll reached to the right most item in the listview.
How can I get that scroll reached to the right most position?
Implement an onScrollListener to your listview, and fetch data through onScroll() method.
There are many libraries for doing this easily. The following is a vertical listview example, but you can always change it to Horizontal and modify the code according to your needs.
https://github.com/shontauro/android-pulltorefresh-and-loadmore
In order to do that, you have to mock the size of the list ruled by your adapter. For example, if the list is called myList, its size is myList.size(), you will have to do something like: myList.add(mockelemnt).
Now that you have mocked the last element, what you may do is to handle it on your adapter method getView():
#Override
public View getView(int position, View convertView, ViewGroup parent){
if (oistion < myList.size(){
//work with conventional view
}else if (postion == myList.size()){
//work with addMore view
}
}
Hope it helps
Inside my getView method I want to get a specific child view. I know that my adapter holds several items, by doing calling getCount:
getCount();
According to the JavaDoc:
public abstract int getCount ()
Added in API level 1
How many items are in the data set represented by this Adapter.
Now in my getView method:
public View getView(final int position, View convertView, ViewGroup parent) {
View lastAddedItem = parent.getChildAt(getCount()-1);
if(lastAddedItem == null) {
Log.w("ListAdapter", "View is null");
}
}
This message always appears in the LogCat, which means that the View I try to grab is Null.
I've also tried this:
View lastAddedItem = parent.getChildAt(parent.getChildCount()-1);
So how can I grab a specific view from my ViewGroup object?
I know that my adapter holds several items, by doing calling
getCount:
Yes it does, but the getCount()(returning the items in the Adapter) method of an adapter has nothing to do with getting the children of a ListView with getChildAt()(where you should use getChildCount() as this will return the Views present in the ViewGroup).
lastAddedItem = parent.getChildAt(parent.getChildCount()-1);
This should return a non-null view, the last view returned by the getView() method.
I just want to animate a specific View in my ViewGroup
If you are going to animate a list row(or part of that row) when it becomes visible than register a scroll listener for the ListView and start the animation from there when the target view is appearing on the screen.
I don't how are you implemented the rest of the adapter, but if you are doing it in the right way, and I am right, the parent only contains the Views being displayed on the device's screen, and each time you pull down or pull up the list, it modifies the content of those views, that is why you get Null.
What you want to achieve (animate a view), should be done in runtime, checking if the view currently being displayed in the screen should be animated or not.
Hope it helps.
I woud like to create a listview that alternates background images. For example, the first item would have background image a and the second item would have background image b and the third backgroud a. In basic terms I would like help on creating a listview that for every odd item (egg first, third, fith) has a certian background image different to those listview items which are even (egg second, fourth, and sixth listview item). Here's an exampe.
http://www.gadgetreview.com/wp-content/uploads/2011/10/SIRI-Reminders.jpg
In this example the speech bubbles are background image and each different background image is a different listview item.
In your list adapter in the getView method divide the position attribute that gets sent into the method by 2. If the remaining number is 0 than you are in the even row of your listview. Depending on that you can change the layout of your list view item.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(position % 2 = 0)
//set layout for even row
}else{
//set layout for odd row
}
Last time that I tried I didn't find an xml parameter to do that, but you can try to use the same workaround used in this question:
Stack Overflow: How do I alternate colors in between Listviews?
you have to make your own custom adapter and then in the following method:
public View getView(int position, View convertView, ViewGroup parent) {
}
you can use position to change the background if position is odd
There is SetEmptyView method in list view use it
listView.setEmptyView( findViewById( R.id.empty_list_view ) );
I am getting some strange behavior from list view. I need to change background color of rows which confirmed the requirement below but it applied on one or two other rows too. which disappeared on scroll.
public View getView(int position, View convertView, ViewGroup parent) {
if (item.get("how_out").equals("not out")) {
v.setBackgroundColor(Color.LTGRAY);
return v;
}
}
thanks
This behavior is due to the recycling property of the listview. The ListView recycles its textviews onScroll. Hence you need to store the states of the textviews using a boolean array and handle the textviews inside onScroll listener of the Listview.