I had a Listview with the following Adapter
SimpleAdapter simpleAdapter
= new SimpleAdapter(NewsListActivity.this,res,R.layout.newslist_adapter,new String[]{"title","description","link"},new int[]{R.id.title,R.id.description,R.id.url});
lView.setAdapter(simpleAdapter);
where lView is the ListView, and res is an HashMap.
In the ListView's onItemClick, I was able to get each View's Description TextView using the Code below
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
View v1 = lView.getChildAt(position - lView.getFirstVisiblePosition());
if(v1 != null){
TextView des = v1.findViewById(R.id.description);
Toast.makeText(getApplicationContext(),des.getText(),0).show(); // returns the Text at exact TextView Clicked
des.setBackgroundColor(R.color.red); //Here is the PROBLEM, It changes the Background Color of TextView I clicked on, but it ALSO changes some other TextView's background color
}
}
As I added in the Comments, The Toast message returns The exact Text in the TextView, but changing the background color also changes some other TextView in the ListView's color
I don't seem to Understand what I am doing wrong.
EDIT
I only posted the portion of the project , so as not mess up all the place with my source code.
It's an RSS feed reader project, but now I realize the problem is with all ListViews. Pleased kindly help with the link below
Android ListView getChild() not working properly
Ok, after months of confusion, pain of being self-taught and punishment of walking alone (no direct access to senior dev for help), I finally realized what I was missing.
The problem arise from ListView re-using view as some sort of memory management techniques (for performance purposes) or so. That's why in my case whenever the background color of a ListView Element is changed and the View is being recycled it affect the background color of whichever item that uses the Recycled view.
As for the fix, this this link should help
Related
I have a main layout. This layout is inflated to the fragment. I have layout named "default_layout_item". The main layout has a header bar, whose background color is blue. Below that there is a listview. Listview item background color is set to white in getview .
Everything works fine The problem what I'm facing is, sometimes header bar color gets changed to white. It's not a part of listview. Then why its happening
Is anyone facing the similar problem? Thanks in Advance..
There are lots of possible issues. Though I would strongly urge you to proof read future questions.. to make it easier on us. Simple thought organization goes a long way.
Following I don't understand most of your question, but I think I might know what you are looking for.. It sounds like you are having issues with the fact Android recycles views in a list view. IE it doesn't actually make a view for every item in a list (if it goes over the screen length) that would be bad. Instead it only makes as many as the screen shows.
To get the correct background you want to set it in your getView in your custom adapter code.
IE
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
//logic for figuring out the color here. Followed by the code to set it.
return rowView;
}
All you need will be in http://www.vogella.com/tutorials/AndroidListView/article.html
I changed the color in this case when I was doing multiple selections on a very custom widget.
If you are trying to set a general color, you should be learning about styles and themes.
I've got an AutoCompleteTextView in my app and I've been tasked with forcing the vertical scroll bar to always show if the results retrieved by said textview are numerous enough to be scrolled (i.e. there are more results than can fit at once in the autocreated listview).
I've tried adding the following xml attributes to the AutoCompleteTextView itself to no avail:
fadeScrollbars="false"
scrollbarFadeDuration="0"
scrollbarAlwaysDrawVertical="true"
I'm thinking if I could somehow obtain a reference to the listview created automatically for the AutoCompleteTextView and applying one or more of the above attributes to it that I could force the scrollbar to always show but I have no idea how to get a reference to that listview.
Thanks
UPDATE
In the Adapter I created for this AutoCompleteTextView, in the Overridden getView() method, I have a reference to the parent view. I can set those attributes above programatically on the parent and I get the desired functionality, the downside is that those attributes are set each time getView is called which isn't the most efficient?
I have tried styles but they don't work properly, so your coded way seems like the only possibility.
But the group is given on every time, so you could just add a boolean for this:
public View getView(int position, View convertView, ViewGroup parent) {
//Change the list attr programmatically becuase sometimes Android sucks :/
if (!_changedListAttr) {
_changedListAttr = true;
ListView list = (ListView) parent;
list.setBackgroundResource(R.color.color_white);
list.setVerticalScrollBarEnabled(false);
list.setDividerHeight(0);
}
i am trying to change the background color of the selected row in a listview and i am able to do it.
But when i am clicking on another row then the background color of the previously selectedrow remains unchanged. I have the position of the previously selected row, Can anybody help me that how can change the background color of previously selected row as it was before??
If you keep track and update the listItems clicked state in your model you can just put the code for displaying has been clicked-color in the adapter and then call
adapter.notifyDatasetChanged();
I think this might be easier if you look at it another way.
Currently, your logic is "if I click on this row, change its color to a special color and change the old row's color back to the original color". However, this doesn't seem to be the logic you actually want. Rather, you want the last clicked (aka selected) row to be a different color.
You haven't posted any code, so I don't know if you are implementing your own ListAdapter in this project. That is the approach I would take. Create a class which extends ListAdapter, and create an additional private variable that stores the position of the last selected row. Then in the overriden getView() method, do a quick check
if(rowPosition == lastSelectedRowPosition)
viewToReturn.setBackgroundColor();
If you aren't sure how to make your own list adapter, check out the tutorial at http://jnastase.alner.net/archive/2010/12/19/custom-android-listadapter.aspx.
In your activity use setOnItemClickListener of Your_List Object.
See Demo Code:
list1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position, long id) {
v.setBackgroundColor(Color.BLUE); // <--- Use color you like here
// ^ this v gives current row.
}
});
This will make background color changed for that row forever.
I have a list of items, which i'd like to "check" with filled star when user clicks on one item in the list.
I have a ListView with text & image, represented in XML layout, and using simple StringAdapter.
I've implemented the above by doing this:
this.listViewSub.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(final AdapterView parent, final View view, final int position,
final long id) {
ImageView img = (ImageView) view.findViewById(R.id.unchkImg);
img.setImageResource(R.drawable.starchk);
I guess its not the right way to do it, but i don't have any idea how else to code it.
This code for some reason changes few random items in the list, and after one click i have about 4-5 items with icon changed.
Any idea how to solve it correctly?
Thanks
It's hard to tell without code, but my first guess is that as the views get recycled, if you don't reset the ImageView to use the default "unchecked" image in the getView method, each time you star an item the view will remain starred, even it is used for a different item. So your adapter should just reset the ImageView's image resource ; though in that case, you'll have to remember which items you starred in order to reset the ImageView correctly : set it to do the default drawable or to the starred one.
At last, after long search - i've found the answer in an article:
http://www.codegod.biz/WebAppCodeGod/Android-ListView-with-dynamic-Images-AID588.aspx
That was a tough one.
I'm currently making a SMS Application in Android, the following is a code snippet from Inbox Listactivity, I have requested a cursor from the contentresolver and used a custom adapter to add custom views into the list.
Now, in the custom view i've got 2 TextViews (tvFullBody,tvBody)...
tvFullBody contains the Full SMS Text while tvBody contains a short preview (35 characters)
The tvFullBody Visibility is by default set to GONE.
My idea is, when the user clicks on a list item, the tvBody should dissappear(GONE) and the tvFullBody should become visible (VISIBLE). On Clicking again, it should revert back to its original state.
//isExpanded is a BitSet of the size = no of list items...keeps track of which items are expanded and which are not
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
if(isExpanded.get(position))
{
v.findViewById(R.id.tvFullBody).setVisibility(View.GONE);
v.findViewById(R.id.tvBody).setVisibility(View.VISIBLE);
}else
{
v.findViewById(R.id.tvFullBody).setVisibility(View.VISIBLE);
v.findViewById(R.id.tvBody).setVisibility(View.GONE);
}
isExpanded.flip(position);
super.onListItemClick(l, v, position, id);
}
The Code works as it is supposed to :) except for an undesired sideeffect....
Every 10th (or so) List Item also gets "toggled".
eg. If i Expand the 1st, then the 11th, 21th list items are also expanded...Although they remain off screen, but on scrolling you get to see the undesired "expansion".
By my novice analysis, i'm guessing Listview keeps track of 10 list items that are currently visible, upon scrolling, it "reuses" those same variables, which is causing this problem...(i didn't check the android source code yet.)
I'd be gratefull for any suggestion, on how i should tackle this! :)
I'm open to alternative methods aswell....Thanks in advance! :)
Your diagnosis of the problem almost correct. What's happening is that Android is reusing the Views it creates to display the list to save memory. Instead of creating a new View for every item in your list, Android creates just enough to fill the screen, updating them to show the relevant data for the items which are currently visible.
So when you show tvFullBody when the user clicks on an item, when that View is re-used later tvFullBody is still visible.
You may have to write you own ListAdapter to make sure the Views are displayed how you want. It should be as simple as extending the ListAdapter you are currently using and overriding the getView() method to ensure that tvFullBody is hidden.