ArrayAdapter custom view state gets repeated when scrolling
<p>I have a ListView that gets populated with custom view items. The custom view consists of an icon, a label and a checkbox. When I first create the list, everything displays as it should. If I scroll down the list, the icons and labels continue to be correct further down the list but the checkbox states start to get mixed up, displaying other items as checked besides the ones I chose. </p>

<p>Example: My list starts with no checkboxes set as checked for any items. I see 10 items on screen. I toggle the checkbox on item 10. It updates appropriately. If I scroll down the list, I find that the checkbox for item 20, item 30, etc. start with the checkbox already toggled even though they were never visible to interact with. If I scroll back and forth repeatedly, more and more items in a non-identifiable pattern appear checked.</p>

<p>List setup in my activity:</p>

<pre><code>@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.default_list);

        profile = (Profile) i.getParcelableExtra("profile");

        ArrayList&lt;Application&gt; apps = new ApplicationListRetriever(this).getApplications(true);

        adapter = new ApplicationsAdapter(this, R.layout.application_list_item, apps, getPackageManager(), profile);
        setListAdapter(adapter);        
    }
</code></pre>

<p>ApplicationsAdapter:</p>

<pre><code>public class ApplicationsAdapter extends ArrayAdapter&lt;Application&gt; {
    private ArrayList&lt;Application&gt; items;
    private PackageManager pm;
    private Profile profile;

    private ArrayList&lt;ApplicationListener&gt; listeners = new ArrayList&lt;ApplicationListener&gt;();

    public ApplicationsAdapter(Context context, int textViewResourceId,
            ArrayList&lt;Application&gt; objects, PackageManager pm, Profile profile) {
        super(context, textViewResourceId, objects);

        this.pm = pm;
        items = objects;
        this.profile = profile;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            LayoutInflater li = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = li.inflate(R.layout.application_list_item, null);
        }
        final Application info = items.get(position);
        if (info != null) {
            TextView text = (TextView) v.findViewById(R.id.label);
            CheckBox check = (CheckBox) v.findViewById(R.id.check);
            ImageView img = (ImageView) v.findViewById(R.id.application_icon);

            //see if the app already is associated and mark checkbox accordingly
            for (Application app : profile.getApps()) {
                if (info.getPackageName().equals(app.getPackageName())) {
                    check.setChecked(true);
                    break;
                }
            }

            check.setOnCheckedChangeListener(new OnCheckedChangeListener() {

                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    for (ApplicationListener listener : listeners) {
                        listener.applicationReceived(info, isChecked);
                    }
                }
            });

            try {
                text.setText(info.getName());
            }
            catch (Exception ex) {
                Log.e("ApplicationsAdapter", "Label could not be set on adapter item", ex);
            }

            if (img != null) {

                try {
                    img.setImageDrawable(pm.getApplicationIcon(info.getPackageName()));
                } catch (NameNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }

        return v;
    }
}
</code></pre>

<p>List item layout:</p>

<pre><code>&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="wrap_content"&gt;
    &lt;ImageView android:id="@+id/application_icon"
        android:layout_centerVertical="true" android:layout_alignParentLeft="true"
        android:layout_width="36dp" android:layout_height="36dp" android:paddingRight="3dp" android:adjustViewBounds="true" /&gt;
    &lt;TextView android:layout_width="wrap_content"
        android:layout_centerVertical="true" android:layout_toRightOf="@+id/application_icon"
        android:layout_height="wrap_content" android:id="@+id/label"
        android:text="Application Name" /&gt;
    &lt;CheckBox android:id="@+id/check"
        android:layout_centerVertical="true" android:layout_alignParentRight="true"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_gravity="right" /&gt;
&lt;/RelativeLayout&gt;
</code></pre>

<p>Also worth noting is if I set a breakpoint on the line where I call <code>check.setChecked(true);</code> it only hits that point if the original item I checked is on screen, never for any of the other items that display as checked.</p>

<p>Any ideas why the later items would display as checked or what I can try to fix it?</p>
