ListPreference keeps repeating rows
<p>I am trying to display a list with checkboxes using a preference activity.  The list is supplied with 121 entries and by debugging I have confirmed that the complete list is passed into the ListPreference.   However the scrollable list ends up with the first 4 entries repeated to the size of the entries i.e. 121.    I found code on here which is as follows.  Stepping through with the debugger it seems that CustomHolder(View row, int position) is supplied with position as first 0 then 2 and so on to 3 at which point it appears as 0 again.   I cant see where and why this is happening so.</p>

<p>First a preference.xml </p>

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;


&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"&gt;
 &lt;PreferenceCategory
            android:title="Your Title"&gt;

&lt;com.Applitastic.CustomListPreference
    android:key="multipref"
    android:id="@+id/multiselectlist"
    android:title="Apps to exclude" android:summary="Specify exclusion"
    android:dialogTitle="Apps to exclude" android:defaultValue="1"/&gt;

&lt;/PreferenceCategory&gt;
&lt;/PreferenceScreen&gt;
</code></pre>

<p>Now an xml for a tablelayout</p>

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="8dip"
android:paddingTop="8dip"
android:paddingLeft="10dip"
android:paddingRight="10dip"&gt;

&lt;TableLayout
    android:id="@+id/custom_list_view_row_table_layout"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:stretchColumns="0"&gt;

    &lt;TableRow
        android:id="@+id/custom_list_view_row_table_row"
        android:gravity="center_vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"&gt;

        &lt;TextView
            android:id="@+id/custom_list_view_row_text_view"
            android:textSize="22sp"
            android:textColor="#000000"  
            android:gravity="center_vertical"
            android:layout_width="160dip" 
            android:layout_height="40dip" /&gt;

        &lt;RadioButton
            android:checked="false"
            android:id="@+id/custom_list_view_row_radio_button"/&gt;
    &lt;/TableRow&gt;
&lt;/TableLayout&gt;
</code></pre>

<p>Now the ListPreference code.</p>

<pre><code>import java.util.ArrayList;

import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.preference.ListPreference;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.widget.TextView;
import android.app.AlertDialog.Builder;
 import android.app.Dialog;

public class CustomListPreference extends ListPreference{
CustomListPreferenceAdapter customListPreferenceAdapter = null;
Context mContext;
private LayoutInflater mInflater;
CharSequence[] entries;
CharSequence[] entryValues;
ArrayList&lt;RadioButton&gt; rButtonList;
SharedPreferences prefs;
SharedPreferences.Editor editor;

public CustomListPreference(Context context, AttributeSet attrs)
{
    super(context, attrs);
    mContext = context;
    mInflater = LayoutInflater.from(context);
    rButtonList = new ArrayList&lt;RadioButton&gt;();
    prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
    editor = prefs.edit();
}

@Override
protected void onPrepareDialogBuilder(Builder builder)
{
    entries = getEntries();
    entryValues = getEntryValues();

    if (entries == null || entryValues == null || entries.length != entryValues.length       
)
    {
        throw new IllegalStateException(
                "ListPreference requires an entries array and an entryValues array
which are both the same length");     
    }

    customListPreferenceAdapter = new CustomListPreferenceAdapter(mContext);

    builder.setAdapter(customListPreferenceAdapter, new   
DialogInterface.OnClickListener()
    {
        public void onClick(DialogInterface dialog, int which)
        {

        }
    });
}

private class CustomListPreferenceAdapter extends BaseAdapter
{        
    public CustomListPreferenceAdapter(Context context)
    {

    }

    public int getCount()
    {
        return entries.length;
    }

    public Object getItem(int position)
    {
        return position;
    }

    public long getItemId(int position)
    {
        return position;
    }

    public View getView(final int position, View convertView, ViewGroup parent)
    {  
        View row = convertView;
        CustomHolder holder = null;

        if(row == null)
        {                                                                   
            row = mInflater.inflate(R.layout.excludeapps, parent, false);
            holder = new CustomHolder(row, position);
            row.setTag(holder);

            // do whatever you need here, for me I wanted the last item to be greyed 
out and unclickable
           // if(position != 3)
            //{
                row.setClickable(true);
                row.setOnClickListener(new View.OnClickListener()
                {
                    public void onClick(View v)
                    {
                        for(RadioButton rb : rButtonList)
                        {
                            if(rb.getId() != position)
                                rb.setChecked(false);
                        }

                        int index = position;
                       // int value = Integer.valueOf((String) entryValues[index]);
                        //editor.putInt("yourPref", value);

                        Dialog mDialog = getDialog();
                        mDialog.dismiss();
                    }
                });
           // }
        } else {
               holder = (CustomHolder) convertView.getTag();
        }

        return row;
    }

    class CustomHolder
    {
        private TextView text = null;
        private RadioButton rButton = null;

        CustomHolder(View row, int position)
        {    
            text = (TextView)row.findViewById(R.id.custom_list_view_row_text_view);
            text.setText(entries[position]);
            rButton =  
(RadioButton)row.findViewById(R.id.custom_list_view_row_radio_button);
            rButton.setId(position);

            // again do whatever you need to, for me I wanted this item to be greyed 
out and unclickable
            //if(position == 3)
            //{
             //   text.setTextColor(Color.LTGRAY);
              //  rButton.setClickable(false);
            //}

            // also need to do something to check your preference and set the right 
button as checked

            rButtonList.add(rButton);
            rButton.setOnCheckedChangeListener(new 
CompoundButton.OnCheckedChangeListener()
            {
                public void onCheckedChanged(CompoundButton buttonView, boolean 
isChecked)
                {
                    if(isChecked)
                    {
                        for(RadioButton rb : rButtonList)
                        {
                            if(rb != buttonView)
                                rb.setChecked(false);
                        }

                        int index = buttonView.getId();
                        //int value = Integer.valueOf((String) entryValues[index]);
                        //editor.putInt("yourPref", value);

                        Dialog mDialog = getDialog();
                        mDialog.dismiss();
                    }
                }
            });
        }
    }
}
}
</code></pre>
