Changing background color on scrollable listview

I have a scrollable listview in which multiple rows can be selected. When selected, the background color changes to green and if selected again it changes back to its original color.

I managed to get that to work but the problem I am having is when I scroll, other rows are being highlighted green that I did not select. I presume this is because the view is being reused/recycled but I'm not sure how to fix the issue.

Code:

public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    myDB = new DatabaseHandler(getActivity());
    listViewSchools = (ListView)getView().findViewById(R.id.listViewFromDB);


    if (myDB.getSchoolCount() != 0){
        SchoolsList.addAll(myDB.getAllSchools());
        isSelected = new boolean[SchoolsList.size()];
    }
    populateSchoolsView();


    listViewSchools.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            t_school item = SchoolsList.get(position);
            if (isSelected[position]) {
                v.setBackgroundColor(getResources().getColor(R.color.orig));
                isSelected[position] = false;
            }
            else if (!isSelected[position]) {
                v.setBackgroundColor(getResources().getColor(R.color.green));
                isSelected[position] = true;
            }
            schoolAdapter.notifyDataSetChanged();

        }
    });
 }

private void populateSchoolsView() {
    schoolAdapter = new SchoolListAdapter();
    listViewSchools.setAdapter(schoolAdapter);
    schoolAdapter.notifyDataSetChanged();

}

private class SchoolListAdapter extends ArrayAdapter<t_school> {
    public SchoolListAdapter() {
        super(getActivity(), R.layout.itemschool_layout, SchoolsList);
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        View row = view;
        ViewHolder holder = new ViewHolder();
        if (row == null) {
            row = getActivity().getLayoutInflater().inflate(R.layout.itemschool_layout, parent, false);
            holder.name = (TextView) row.findViewById(R.id.school_name);
            row.setTag(holder);
        }
        else{
            holder = (ViewHolder)row.getTag();
        }

        t_school currentSchool = SchoolsList.get(position);

        if(currentSchool!=null){
            holder.name.setText(currentSchool.getInfo());

        }

        return row;
    }
}

public class ViewHolder
{
    TextView name;

}

EDIT

I attempted to implement getItemViewType() and getViewTypeCount() but I'm not sure if I'm on the right track. I followed this tutorial for reference: http://android.amberfog.com/?p=296 but I could use some more guidance on what I'm missing in those methods and if I'm utilizing them correctly in getView().

Edited Code:

public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    myDB = new DatabaseHandler(getActivity());
    if(myDB.getSchoolCount()==0)
        Toast.makeText(getActivity().getApplicationContext(), "Please Import Data", Toast.LENGTH_LONG).show();
    listViewSchools = (ListView)getView().findViewById(R.id.listViewFromDB);

    registerForContextMenu(listViewSchools);


    listViewSchools.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            longClickedItemIndex = position;
            return false;
        }
    });

    if (myDB.getSchoolCount() != 0){
        SchoolsList.addAll(myDB.getAllSchools());
        isSelected = new boolean[SchoolsList.size()];
    }
    populateSchoolsView();


    listViewSchools.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            t_school item = SchoolsList.get(position);
            if (isSelected[position]) {
                v.setBackgroundColor(getResources().getColor(R.color.orig));
                isSelected[position] = false;
            }
            else if (!isSelected[position]) {
                v.setBackgroundColor(getResources().getColor(R.color.green));
                isSelected[position] = true;
            }
            schoolAdapter.notifyDataSetChanged();

        }
    });

}

private void populateSchoolsView() {
    schoolAdapter = new SchoolListAdapter();
    listViewSchools.setAdapter(schoolAdapter);
    schoolAdapter.notifyDataSetChanged();

}

private class SchoolListAdapter extends ArrayAdapter<t_school> {
    public SchoolListAdapter() {
        super(getActivity(), R.layout.itemschool_layout, SchoolsList);
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {
        return isSelected[position] ? 1 : 0;
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        View row = view;
        ViewHolder holder;
        int type = getItemViewType(position);

        if (row == null) {
            holder = new ViewHolder();
            switch ((type)) {
                case 1:
                    row = getActivity().getLayoutInflater().inflate(R.layout.itemschool_layout, parent, false);
                    holder.name = (TextView) row.findViewById(R.id.school_name);
                    break;

                case 0:
                    row = getActivity().getLayoutInflater().inflate(R.layout.itemschool_layout, parent, false);
                    holder.name = (TextView) row.findViewById(R.id.school_name);
                    break;

            }
            row.setTag(holder);
        }
        else{
            holder = (ViewHolder)row.getTag();
        }

        t_school currentSchool = SchoolsList.get(position);
        if(currentSchool!=null){
            holder.name.setText(currentSchool.getSchool_info());

        }

        return row;
    }
}

public class ViewHolder
{
    TextView name;

}   

Answers


What you are expiring is the Recycling mechanism of the Listview.

You change the appearance of your Listitem and get the same Item again when you scrolling further down.

You could always reset the color but the clean solution would be to provide 2 Item Types.

@Override
public int getViewTypeCount() {
    return 2;
}

@Override
public int getItemViewType(int position) {
    return isSelected[position] ? 1 : 0;
}

that way the ListView provides you with recyled Items of the same type.


Need Your Help

jquery validate form input if certain check boxes are checked

jquery checkbox validation

I have a multipart form that takes basic user information at the beginning with some jquery.validate error checking to see if the fields have been filled in and the email address is valid.