I have a strange problem. I am setting the background color of the items of a listview like so:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
...
if (status == true) {
row.setBackgroundColor(Color.argb(255,0,85,187));
}
else {
if (morestuff) {
row.setBackgroundColor(Color.argb(128,255,0,0));
}
}
...
}
This seems to work. However, when i scroll on the listview, and then back, some of the rows have acquired a color from another row without being set by this code. I suspect the listview is recycling the views as an optimization.
How can I fix this?
The getView will be called all the time when the listview is drawn. Simply taking it will be called when we do a small change example do a small scroll
If you want to set color to a specific row, Just do it by checking the position (First argument of getview).
The list view is definately recycling views as an optimization. You should look at the efficient list view example for ideas.
Related
I read many other posts, but most, if not all of them tell you to override one of the methods and put change the background then. I want to change it outside of the ListView Adapter class, so I tried doing this. It doesn't seem to work. I do however get the object, nut it wont change its background.
RelativeLayout item;
item = (RelativeLayout) listView.getAdapter().getView(0, null, listView);
item.setBackgroundColor(Color.YELLOW);
Thank you.
Find the nearest time save it in a variable and call adapter.notifyDataSetChanged()
public View getView(int position, View convertView, ViewGroup parent){
if(time is nerest time) {
convertView. setBackgroundColor(Color. YELLOW)
} else {
convertView. setBackgroundColor("default color")
}
}
I'm Noob at Java Android.
I searched more about my question and I found that I can use
listView.getFirstVisiblePosition();
To get my first visible position. How can I implement a new Background Resource only to my first visible position?
I tried to do that by far.
View get = lv.getFirstVisiblePosition()
get.setBackgroundResource(R.drawable.newconversation);
Thanks.
There is a method in your adapter which controls your list items views
#Override
public View getView(int position, View convertView, ViewGroup parent) {
You can just use this condition :
if(position == 0)
//set your background
After convertView has been inflated
getFirstVisiblePosition() returns an Integer position. You want to get the view at that position.
Try
View view = list.getChildAt(list.getFirstVisiblePosition());
Then set your background on the view.
In myadapter.java I have following code:
public View getView(int position,View convertView,ViewGroup parent) {
View view=null;
if(convertView!=null)view=convertView;else view=newView(context,parent);
HashMap<String,String> d=new HashMap<String,String>();
d=data.get(position);
String _r=d.get("r");
String out=d.get("out");
Typeface mf=Typeface.createFromAsset(context.getAssets(),"fonts/mf.ttf");
TextView txt=(TextView)view.findViewById(R.id.c_n);
txt.setText(_r);
txt.setTypeface(mf);
if(out.equals("yes") && !d.get("sid").equals("-1")) {
ImageView imag=(ImageView)view.findViewById(R.id.myimage);
imag.setVisibility(imag.VISIBLE);//This fires sometimes while scroll, while
//I scroll & where I don't need it.
//view.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.c_c));
//^ same as setVisibility.
}
...
return view;
}
When I start my app, this list is OK. But, while I scroll, imag.setVisibility(imag.VISIBLE); fires sometimes where I don't need it, like listview generates every scroll event. Some ImageViews become visible, that weren't at apps start.
How do I fix this?
The problem is caused by convertView and the way it is used for re-cycling existing views.
Example - suppose your list adapter has 20 items but the ListView can only display 5 on the screen. Those 5 list item 'views' will be re-cycled by being passed as the convertView parameter when the ListView is scrolled.
Once you set the visibility of the ImageView, it will remain set in the convertView. In other words you need to set it to INVISIBLE or GONE if you don't want it visible...
ImageView imag=(ImageView)view.findViewById(R.id.myimage);
if (d.get("ms").equals("yes") && !d.get("sid").equals("-1")) {
imag.setVisibility(View.VISIBLE);
}
else
imag.setVisibility(View.INVISIBLE); // Or use View.GONE depending on what you need
I am developing an application in which I have to show ratings depending on the values that I am receiving after parsing the XML response in listview. I have implemented it using the Custom Adapter and showing the images in the getView() method like :
String rating = Constants.menuRatingList.get(position);
if (rating.equals("1")) {
rateImg1.setImageResource(R.drawable.stary);
}
The problem is when I scroll the down to the last item and again move upwards, it is redrawing the list row.
Someone please suggest me approach to stop the redrawing the list row and set the image value permanently.
How do you create the rateImg1 variable?
Maybe you should get it from the view that is passed to the getView() method?
Something like this:
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
view = LayoutInflater.from(ctx).inflate(R.layout.my_layout, parent, false);
}
((ImageView) view.findViewById(R.id.my_image)).setImageResource(R.drawable.some_drawable);
return view;
}
Also you can implement getViewTypeCount() and getItemViewType() and check them in the above method not to redraw the same image if it is already set.
I am working on customize (inflated) list view. In which I have used the text and background image for text (as per the condition).
Now I am facing problem in scrolling the list view that background of text view is overlapping to the other text views.
Here is the sample code:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View icontextlayout=convertView;
icontextlayout= inflater.inflate(R.layout.layout_complex_list, null);
TextView Txt1=(TextView)icontextlayout.findViewById(R.id.txt1);
if(disp1==true)
{
Txt1.setBackgroundResource(R.drawable.pic)
}
else
Txt1.setText("Text1 "+strUser);//
TextView Txt2=(TextView)icontextlayout.findViewById(R.id.txt2);
if(disp2==true)
{
Txt2.setBackgroundResource(R.drawable.pic);
}
else Txt2.setText("Text2: "+strIndus);
return icontextlayout;
}
Could you please help me out that background image pic do not overlap the others background.
Thanking you...
The problem is that you must set a default background when you don't need a background. For instance:
if(disp1==true){
Txt1.setBackgroundResource(R.drawable.pic);
Txt1.setText("");
}
else{
Txt1.setText("Text1 "+strUser);//
Txt1.setBackgroundDrawable(null);
}
Also, if you don't mind, I like to give you my opinion about your code:
That's not they way in which list are usually populated. Take a look at this answer: How to load the Listview "smoothly" in android
convertView is used to reuse rows. In your case you are doing something like:
View icontextlayout=convertView;
icontextlayout= inflater.inflate(R.layout.layout_complex_list, null);
Which is bad, because you are not actually using the convertView (when you call inflater.inflate) it will create a new row, thus your list will be really slow.
if(disp2==true) is redundant. You should consider using just: if(disp2).