Search code examples
androidandroid-listviewtextviewsimplecursoradapter

text color passes to recycled list items in my adapter


I'm trying to change the text colour of a textview inside a listitem if the text is a number under 5. But when i scroll up / down, the colours apply to recycled items. I've looked around and i don't really understand how these recycled items work.

Fragment Class

ListAdapter adapter = new RacesAdapter(getActivity(), racesList,
            R.layout.list_item,
            new String[] { TAG_NAME, TAG_GOAL, TAG_NUMENTRANTS }, new int[] {
                    R.id.gameLabel, R.id.goalLabel, R.id.entrantsLabel});
    setListAdapter(adapter);

RacesAdapter Class (is a modified SimpleAdapter) (Look in bindView() for my code)

public View getView(int position, View convertView, ViewGroup parent) {
    return createViewFromResource(position, convertView, parent, mResource);
}

private View createViewFromResource(int position, View convertView,
        ViewGroup parent, int resource) {

    View v;
    if (convertView == null) {
        v = mInflater.inflate(resource, parent, false);
    } else {
        v = convertView;
    }

    bindView(position, v);
    return v;
}

public void setDropDownViewResource(int resource) {
    this.mDropDownResource = resource;
}

@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
    return createViewFromResource(position, convertView, parent, mDropDownResource);
}

@SuppressWarnings("rawtypes")
private void bindView(int position, View view) {
    final Map dataSet = mData.get(position);
    if (dataSet == null) {
        return;
    }

    final String[] from = mFrom;
    final int[] to = mTo;
    final int len = to.length;

    for (int i = 0; i < len; i++) {
        final View v = view.findViewById(to[i]);
        if (v != null) {


            final Object data = dataSet.get(from[i]);
            String text = data == null ? "" : data.toString();
            if (text == null) {
                text = "";
            }


            boolean bound = false;
            if (mViewBinder != null) {
                bound = mViewBinder.setViewValue(v, data, text);
            }



            if (!bound) {
                if (v instanceof TextView) {
                    if(v.getId()==R.id.entrantsLabel){
                        if(Integer.parseInt(text) < 5){((TextView) v).setTextColor(Color.RED);}
                    }
                    setViewText((TextView) v, text);
                } 
                else if (v instanceof ImageView) {
                    if (data instanceof Integer) {
                        setViewImage((ImageView) v, (Integer) data);                            
                    } else {
                        setViewImage((ImageView) v, text);
                    }
                } else {
                    throw new IllegalStateException(v.getClass().getName() + " is not a " +
                            " view that can be bounds by this SimpleAdapter");
                }
            }
        }
    }
}


public ViewBinder getViewBinder() {
    return mViewBinder;
}

Solution

  • What you should do is, in bindView(), set your text color to a default. Then, it may or may not change to Color.RED. If it does, it's red, otherwise, it's default.

    So, something like this:

    private void bindView(int position, View view) {
        // ...
    
        for (int i = 0; i < len; i++) {
            final View v = view.findViewById(to[i]);
            if (v != null) {
    
                v.setTextColor(Color.BLACK); // For example
                // ...
    
                if (!bound) {
                    if (v instanceof TextView) {
                        if(v.getId()==R.id.entrantsLabel){
                            if(Integer.parseInt(text) < 5){((TextView) v).setTextColor(Color.RED);}
                        }
                        // ...
                    } 
                    // ...
                }
            }
        }
    }