I have a listview which contains a baseadapter which gets data from the database in Json format. All of that works my problem is that I have an ImageButton with a blue background however if certain conditions in the IF statement evaluate to true then it changes the ImageButton background to light orange. This works when I'm scrolling down the listview but when I scroll up the Listview then a bunch of other rows that don't meet the requirement turn the image Orange. I do not know how this is happening this is my code
public class LocalFeed_CustomView extends BaseAdapter {
JSONObject names;
Context ctx;
LayoutInflater myiflater;
Activity m;
ImageButton reputation_add;
public LocalFeed_CustomView(JSONObject arr,Context c) {
ctx = c;
names = arr;
}
@Override
public int getCount() {
try {
JSONArray jaLocalstreams = names.getJSONArray("localstreams");
return jaLocalstreams.length();
} catch (Exception e) {
Toast.makeText(ctx,"Error: Please try again",Toast.LENGTH_LONG).show();
return names.length();
}
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position,View convertView, ViewGroup parent) {
try {
if(convertView==null) {
LayoutInflater li = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = li.inflate(R.layout.customadapter, null);
}
reputation_add= (ImageButton)convertView.findViewById(R.id.reputation_add);
SharedPreferences myaccount= ctx.getSharedPreferences("userInfo", MODE_PRIVATE);
// This gets user ID and matches it with Data_ID which come from the database
int Profile_ID = myaccount.getInt("id",0);
JSONArray jaLocalstreams = names.getJSONArray("localstreams");
final JSONObject jsonObject = jaLocalstreams.getJSONObject(position);
int Data_ID= jsonObject.getInt("myid");
// IF the statement is true then the ImageButton Background changes color
if(Data_ID==Profile_ID)
{
reputation_add.setBackgroundResource((R.drawable.borders));
}
return convertView;
} catch (Exception e) {
e.printStackTrace();
}
return convertView;
}
}
As you see above only when the Data_ID=Profile_ID evaluate to true should the ImageButton change background colors and again it works perfectly when scrolling down the Listview but when going back up the ImageButton turns Orange on rows that it does not suppose to. Here are images to clarify this some more. First & Foremost on the picture below the Orange background where the checkmark is; is the ImageButton the original color is blue as stated before. To the Left of that Image is Profile_ID which is 32 then if You look up by the name there is a number there which is Data_ID which is 32 hence the image background turns orange as it suppose to.
This next image is when I'm Scrolling back up and look at the numbers on this row as you can see Profile_ID is 32 but Data_ID is 0 but it still turned the background Orange which shouldn't happen because clearly 32==0 is false. Any suggestions would be much appreciated.
I think the issue is caused because of the recycling mechanism of the ListView. Inside getView(), every time you have an if statement, you must also set an else statement to do the opposite. Otherwise, when an item is recycled (when you scroll up, most probably), the condition already happened before and the background has already changed. You're using the same recycled item with the alternated background and you never set it back to the original background if the condition does no longer hold. It should be:
...
if (condition_holds) {
reputation_add.setBackgroundResource((R.drawable.borders));
} else {
reputation_add.setBackgroundResource((R.drawable.original_background));
}
In addition, I see you don't use ViewHolders and instead you always call to findViewById(). This is il-adviced, especially if you have plenty of Views. See a previous post by me: https://stackoverflow.com/questions/32775508/issue-in-display-phone-contact-list-in-android-application-very-slow/32775803#32775803