ListPreference不断重复行

时间:2011-09-22 22:16:33

标签: android

我正在尝试使用首选项活动显示带有复选框的列表。该列表提供了121个条目,通过调试我已确认完整列表已传递到ListPreference。然而,可滚动列表最终以前4个条目重复到条目的大小,即121.我在这里找到了如下代码。使用调试器后,看起来CustomHolder(View row,int position)的位置为第一个0然后是2,依此类推到3,此时它再次显示为0。我不知道发生这种情况的原因和原因。

首先是preference.xml

<?xml version="1.0" encoding="utf-8"?>


<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
 <PreferenceCategory
            android:title="Your Title">

<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"/>

</PreferenceCategory>
</PreferenceScreen>

现在是一个用于tablelayout的xml

<?xml version="1.0" encoding="utf-8"?>
<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">

<TableLayout
    android:id="@+id/custom_list_view_row_table_layout"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:stretchColumns="0">

    <TableRow
        android:id="@+id/custom_list_view_row_table_row"
        android:gravity="center_vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <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" />

        <RadioButton
            android:checked="false"
            android:id="@+id/custom_list_view_row_radio_button"/>
    </TableRow>
</TableLayout>

现在是ListPreference代码。

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<RadioButton> rButtonList;
SharedPreferences prefs;
SharedPreferences.Editor editor;

public CustomListPreference(Context context, AttributeSet attrs)
{
    super(context, attrs);
    mContext = context;
    mInflater = LayoutInflater.from(context);
    rButtonList = new ArrayList<RadioButton>();
    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();
                    }
                }
            });
        }
    }
}
}

1 个答案:

答案 0 :(得分:1)

好吧,看看getView。您对循环视图的最后操作是:

// ...
} else {
    holder = (CustomHolder) convertView.getTag();

    // Edit: how to update the holder (see explanation further below)
    holder.updateText(position);
}

return row;

您必须使用该位置的新数据填充并更新该持有人。在你的情况下,它保持不变(所以在if部分中设置的数据)。

修改:如何更新持有人?

假设您要在CustomHolder中实现此方法,那么您可以按照显示的方式更新它:

public void updateText(int position) {
    text.setText(entries[position]);
}

注意:常见模式不是在持有者中实现更新本身。我的持有人通常是一个有holder.title公共成员的班级(没有方法,只是参考的容器),所以我可以直接从holder.title.setTitle(...)拨打getView