开发者

When I scroll a listview with a custom adapter too fast up and down, getView() starts behaving oddly. Why?

开发者 https://www.devze.com 2023-01-10 11:38 出处:网络
I have a listview with a custom arrayadapter that handles about 15 strings. The style of each row alternates (between labels and values for those labels--for example row 1 could be \"email address\" a

I have a listview with a custom arrayadapter that handles about 15 strings. The style of each row alternates (between labels and values for those labels--for example row 1 could be "email address" and row 2 would be the actual email address). I'm changi开发者_运维知识库ng the style of each row to alternate like this in the arrayadapter's getView() method. So if the item at the current position is a label, I'll change the styling from the default row style (which is what the values have applied to them). When the listview first loads, the styling is perfect and just how I want it to be. If I scroll the list slowly up or down, it stays that way. However, if I scroll the list fast up and down, the styling of the value rows starts changing to that of the label ones until all of the rows have the styling of a label row. Does anyone know why this would be happening? I've used custom adapters on other listviews in the app with no problems like this.

Edit: Found out that it also changes all of the rows to the label styling on portrait->landscape orientation changes. Doesn't do this on landscape->portrait changes. Below is the adapter I'm using. Am I missing something?

public class DetailsAdapter extends ArrayAdapter<String> {

private TextView text = null;
private String item = null;

public DetailsAdapter(Context context, int resource, int textViewResourceId, String[] objects) {
    super(context, resource, textViewResourceId, objects);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    text = (TextView) super.getView(position, convertView, parent);
    item = getItem(position);
    if (item.equals("Name") || item.equals("Mobile") || item.equals("Home") || item.equals("Email") || item.equals("Address")) {
        text.setBackgroundColor(0xFF575757);
        text.setTextSize(15);
        text.setTypeface(null, Typeface.BOLD);
        text.setPadding(8, 5, 0, 5);
    } else {
        text.setPadding(15, 15, 0, 15);
    }
    return text;
}

@Override
public boolean isEnabled(int position) {
    item = getItem(position);
    if (item.equals("Name") || item.equals("Mobile") || item.equals("Home") || item.equals("Email") || item.equals("Address")) {
        return false;
    } else {
        return true;
    }
}
}


Android reuses views fairly aggressively, and it is quite possible that a view that was used as an email address row gets reused on a row that's supposed to display a label, and vice-versa.

As a result, you cannot rely on "default" values. Set your padding, typeface, text size and background color in all cases:

if (item.equals("Name") || item.equals("Mobile") || item.equals("Home") || item.equals("Email") || item.equals("Address")) {
    text.setBackgroundColor(0xFF575757);
    text.setTextSize(15);
    text.setTypeface(null, Typeface.BOLD);
    text.setPadding(8, 5, 0, 5);
} else {
    text.setBackgroundColor(DEFAULT_BACKGROUND);
    text.setTextSize(DEFAULT_TEXT_SIZE);
    text.setTypeface(null, DEFAULT_TYPEFACE);
    text.setPadding(15, 15, 0, 15);
}


Don't need to do anything. I too faced the same problem and solved it like this:

Just inside the getView method add a first line

convertView=null; 

It wont redraw the view immediately destroyed but instead would create new ones each time based on your logic (even odd or whatever)

0

精彩评论

暂无评论...
验证码 换一张
取 消