пользовательская строка в listPreference?

Я пытаюсь создать ListPreference, но каким-то образом отключаю один из элементов. Вроде как серый или что-то в этом роде и не иметь возможности выбрать его. Это будет предстоящая функция, и я хочу, чтобы ее нельзя было выбрать в списке.

Я создал собственный класс ListPreference и в этом классе собственный адаптер, надеясь использовать адаптер для создания того, что я хочу.

Код работает и устанавливает адаптер, но ни одна из функций адаптера не вызывается. Я устанавливаю точки останова на методы, такие как getCount(), но они никогда не вызываются.

Вот мой код. Custom ListPreference взят с http://blog.350nice.com/wp/archives/240

import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.preference.ListPreference;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.app.AlertDialog.Builder;

public class CustomListPreference extends ListPreference {

    private boolean[] mClickedDialogEntryIndices;
    CustomListPreferenceAdapter customListPreferenceAdapter = null;
    Context mContext;

    public CustomListPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        mClickedDialogEntryIndices = new boolean[getEntries().length];
    }

    @Override
    protected void onPrepareDialogBuilder(Builder builder) {
        CharSequence[] entries = getEntries();
        CharSequence[] 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");
        }
        builder.setMultiChoiceItems(entries, mClickedDialogEntryIndices,
                new DialogInterface.OnMultiChoiceClickListener() {

                    public void onClick(DialogInterface dialog, int which,
                            boolean val) {
                        mClickedDialogEntryIndices[which] = val;
                    }
                });
        // setting my custom list adapter
        customListPreferenceAdapter = new CustomListPreferenceAdapter(mContext);
        builder.setAdapter(customListPreferenceAdapter, null);
    }

    private class CustomListPreferenceAdapter extends BaseAdapter {

        public CustomListPreferenceAdapter(Context context) {}

        public int getCount() {
            return 1;
        }

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

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

        public View getView(int position, View convertView, ViewGroup parent) {
            convertView.setBackgroundColor(Color.BLUE);
            return convertView;
        }
    }
}

person Bob    schedule 28.12.2010    source источник
comment
Как вы используете этот CustomListPreference? Вы раздуваете пользовательский интерфейс для своей PreferenceActivity из xml? Построить это в коде?   -  person CaseyB    schedule 29.12.2010
comment
Я определяю предпочтение для своей PreferenceActivity через xml, и в этом xml у меня есть элемент, который является этим настраиваемым listPreference, используя полное имя пакета для ссылки на этот класс.   -  person Bob    schedule 29.12.2010
comment
Обновление: я заставил адаптер работать, используя builder.setSingleChoiceItems() и передав свой адаптер в качестве первого аргумента. Этот метод перегружается несколько раз, поэтому, если вы читаете это, просто посмотрите его в документации. Сейчас работаю над тем, чтобы связать все воедино.   -  person Bob    schedule 29.12.2010


Ответы (9)


Хорошо, я заставил это работать, в основном. Мне пришлось использовать пользовательский класс, который расширяет ListPreference. Затем внутри этого мне пришлось создать собственный класс адаптера, как и для ListView, и установить его для построителя с помощью builder.setAdapter(). Мне также пришлось определить прослушиватели для строк RadioButtons и ListView, которые обрабатывали снятие отметки с RadioButtons и т.д. Единственные проблемы, которые у меня все еще есть, это то, что у моего пользовательского ListPreference есть кнопки «ОК» и «Отмена», а у ListPreference есть только кнопка «Отмена». Я не знаю, как убрать кнопку ОК. Кроме того, я не могу выделить строки, когда нажимаю на них, как в обычном ListPreference.

Код Java для пользовательского класса ListPreference. Обязательно помните о таких вещах, как имя вашего пакета, имя предпочтения (ключ), ваши записи и значения для ListPreference, а также имена ваших элементов xml.

package your.package.here;

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.Dialog;
import android.app.AlertDialog.Builder;

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.custom_list_preference_row, 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();
                        }
                    });
                }
            }

            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();
                        }
                    }
                });
            }
        }
    }
}

XML для моего PreferenceActivity. Это не мой полный xml, для простоты я убрал все остальные элементы предпочтений. Опять же, не забывайте об имени пакета, на пользовательский класс ListPreference нужно ссылаться по имени пакета. Также обратите внимание на имена предпочтений и имена массивов, которые содержат записи и значения.

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

<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android">

        <PreferenceCategory
                android:title="Your Title">

                <your.package.here.CustomListPreference
                    android:key="yourPref"
                    android:title="Your Title"
                    android:dialogTitle="Your Title"
                    android:summary="Your Summary"
                    android:defaultValue="1"
                    android:entries="@array/yourArray"
                    android:entryValues="@array/yourValues"/>

        </PreferenceCategory>
</PreferenceScreen>

Мой xml для строки представления списка диалогового окна. В методе getView обязательно используйте имя этого 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>

</LinearLayout>

Наконец, в разделе res/values ​​находится мой файл array.xml, содержащий имена и значения записей для ListPreference. Опять же, укоротил мой для простоты.

<?xml version="1.0" encoding="utf-8"?>
<resources> 
    <string-array name="yourArray">
        <item>Item 1</item>
        <item>Item 2</item>
        <item>Item 3</item>
        <item>Item 4</item>
    </string-array>

    <string-array name="yourValues">
        <item>0</item>
        <item>1</item>
        <item>2</item>
        <item>3</item>
    </string-array>
</resources>
person Bob    schedule 29.12.2010
comment
Чтобы убрать кнопку ОК, поместите builder.setPositiveButton(null, null); сразу после protected void onPrepareDialogBuilder (строитель Builder) { - person Intrications; 10.03.2011
comment
Это работает отлично, пока количество элементов (в вашем случае 4) не превысит размер экрана; не могли бы вы посмотреть это один раз? В случае, когда элементы превышают размер экрана, старые элементы повторяются вместо отображения следующих элементов. - person Vamsi; 10.05.2012
comment
повторение записей, когда количество записей больше, чем количество записей, размещенных на экране, было решено, через некоторое время будет опубликован код - person Vamsi; 11.05.2012
comment
выбранная радиокнопка не работает. и она не отмечена! как это решить?! - person CooL i3oY; 05.09.2012
comment
это смоделированный проект, в котором есть проблема. проблема в том, что выбранная радиокнопка не работает .com/file/7491144301/ - person CooL i3oY; 05.09.2012
comment
Привет @Вамси. Я пытаюсь настроить пользовательский список, все работает нормально, пока количество элементов не увеличит размер экрана, здесь представление списка в диалоговом окне повторяет старые элементы вместо нового элемента. Как вы написали в одном из комментариев, вы решили эту проблему, пожалуйста, объясните мне, как вы ее решили. Спасибо. - person Dory; 23.09.2013
comment
@NidhiGondhia Пожалуйста, проверьте недавно добавленный ответ. Это сработало в моем случае. - person Vamsi; 26.09.2013
comment
@Vamsi Эй, я немного застрял. У меня такая же проблема, как и здесь. Но реализация немного другая. Вот мой вопрос. Можете ли вы помочь мне с этим? stackoverflow.com/questions/38331665/ - person impossible; 12.07.2016
comment
Также мы должны вызвать callChangeListener(newValue); после того, как мы отредактируем предпочтение, чтобы убедиться, что любой OnPreferenceChangeListener активируется из-за изменения. - person M.Paunov; 25.08.2017

Это хорошо сработало для меня. Я использовал подход с адаптером, который внедряет в представление обернутый адаптер.

Вот базовый обернутый класс адаптера:

import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.WrapperListAdapter;

class ListPrefWrapperAdapter implements WrapperListAdapter {
    private ListAdapter mOrigAdapter;

    public ListPrefWrapperAdapter(ListAdapter origAdapter) {
        mOrigAdapter = origAdapter;
    }

    @Override
    public ListAdapter getWrappedAdapter() {
        return mOrigAdapter;
    }

    @Override
    public boolean areAllItemsEnabled() {
        return getWrappedAdapter().areAllItemsEnabled();
    }

    @Override
    public boolean isEnabled(int position) {
        return getWrappedAdapter().isEnabled(position);
    }

    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
        getWrappedAdapter().registerDataSetObserver(observer);
    }

    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {
        getWrappedAdapter().unregisterDataSetObserver(observer);
    }

    @Override
    public int getCount() {
        return getWrappedAdapter().getCount();
    }

    @Override
    public Object getItem(int position) {
        return getWrappedAdapter().getItem(position);
    }

    @Override
    public long getItemId(int position) {
        return getWrappedAdapter().getItemId(position);
    }

    @Override
    public boolean hasStableIds() {
        return getWrappedAdapter().hasStableIds();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return getWrappedAdapter().getView(position, convertView, parent);
    }

    @Override
    public int getItemViewType(int position) {
        return getWrappedAdapter().getItemViewType(position);
    }

    @Override
    public int getViewTypeCount() {
        return getWrappedAdapter().getViewTypeCount();
    }

    @Override
    public boolean isEmpty() {
        return getWrappedAdapter().isEmpty();
    }
}

Вот базовый класс CustomListPreference, использующий ListPrefWrapperAdapter:

import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
import android.widget.ListAdapter;
import android.widget.ListView;

public class CustomListPreference extends ListPreference {
    public CustomListPreference(Context context) {
        super(context);
    }

    public CustomListPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void showDialog(Bundle state) {
        super.showDialog(state);
        AlertDialog dialog = (AlertDialog) getDialog();
        ListView listView = dialog.getListView();
        ListAdapter adapter = listView.getAdapter();
        final ListPrefWrapperAdapter fontTypeAdapter = createWrapperAdapter(adapter);

        // Adjust the selection because resetting the adapter loses the selection.
        int selectedPosition = findIndexOfValue(getValue());
        listView.setAdapter(fontTypeAdapter);
        if (selectedPosition != -1) {
            listView.setItemChecked(selectedPosition, true);
            listView.setSelection(selectedPosition);
        }
    }

    protected ListPrefWrapperAdapter createWrapperAdapter(ListAdapter origAdapter) {
        return new ListPrefWrapperAdapter(origAdapter);
    }

}

Наконец, вот производные классы, которые отключают и включают определенные строки:

import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckedTextView;
import android.widget.ListAdapter;

public class FontTypePreference extends CustomListPreference {

    public FontTypePreference(Context context) {
        super(context);
    }

    public FontTypePreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected ListPrefWrapperAdapter createWrapperAdapter(ListAdapter origAdapter) {
        return new Adapter(origAdapter);
    }

    private class Adapter extends ListPrefWrapperAdapter {
        private static final float TEXT_SIZE = 25.0f;
        private static final int STARTING_UPGRADE_REQUIRED_INDEX = 8;

        public Adapter(ListAdapter origAdapter) {
            super(origAdapter);
        }

        @Override
        public boolean areAllItemsEnabled() {
            return false;
        }

        @Override
        public boolean isEnabled(int position) {
            return position < STARTING_UPGRADE_REQUIRED_INDEX;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            CheckedTextView textView = (CheckedTextView) getWrappedAdapter()
                    .getView(position, convertView, parent);
            textView.setTextColor(position < STARTING_UPGRADE_REQUIRED_INDEX ?
                    Color.BLACK : Color.RED);
            return textView;
        }


    }

}

Я тестировал этот код только на SDK версии 15 и выше.

person Roger Jack    schedule 01.02.2015

Вероятно, придется добавить editor.commit(); после каждого editor.putInt(...)

person Amitav Paul    schedule 23.04.2012

функция getcount() возвращает неверный результат.

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

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

    public long getItemId(int position)
    {
        return position;
    }
person hyongbai    schedule 03.11.2011
comment
Эй, я немного застрял. У меня такая же проблема, как и здесь. Но реализация немного другая. Вот мой вопрос. Можете ли вы помочь мне с этим? stackoverflow.com/questions/38331665/ - person impossible; 12.07.2016

Спасибо Бобу за этот ответ и Вамси за попытку исправить ошибку с повторяющимися записями, но исправление Вамси не сработало для меня. Приходилось хранить массив представлений и возвращать его на позицию, если она уже была создана раньше. Итак, вот мой полный класс CustomListPreferenceAdapter. Он также содержит исправление для проверки выбранного значения предпочтения.

private class CustomListPreferenceAdapter extends BaseAdapter
{
    View[] Views;

    public CustomListPreferenceAdapter(Context context)
    {
        Views = new View[entries.length];
    }

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

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

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

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

        if(row == null)
        {                                                             
            row = mInflater.inflate(R.layout.listrow, parent, false);
            holder = new CustomHolder(row, position);
            row.setTag(holder);
            Views[position] = row;
        }

        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);

            if(getPersistedString("").compareTo((String)entryValues[position])==0)
                rButton.setChecked(true);

            rButtonList.add(rButton);
        }
    }
}
person Xav    schedule 02.10.2013

Я думаю, вы можете добиться именно того, чего хотите, установив для включенного флага ListPreference значение false:

ListPreference lp = (ListPreference) findPreference("YOUR_KEY");
lp.setEnabled(false);

Это затемняет описание и делает его недоступным для выбора.

person Malthan    schedule 07.01.2013
comment
это отключит весь ListPreference, а OP хочет отключить только некоторые элементы ВНУТРИ ListPreference - person jfortunato; 08.01.2013

изменил код, как показано ниже -

if(row == null) {                                                                   
    row = mInflater.inflate(R.layout.custom_list_preference_row, parent, false);
    holder = new CustomHolder(row, position);
} else {
    holder = row.getTag()
}
// update the holder with new Text/Drawables etc.,
row.setTag(holder);
return row;

PS - NidhiGondhia запросил модифицированный код, так как в комментариях это не может быть, обновив модифицированный код здесь.

person Vamsi    schedule 26.09.2013
comment
Эй, я прокомментировал вверху, но на случай, если вы этого не совсем заметите. Я прошу вас помочь мне с моей проблемой записи в listpreference, которые раздуваются в расширении предпочтений"> stackoverflow.com/questions/38331665/ - person impossible; 12.07.2016

Вы можете сделать это проще.

Шаги:

  1. Расширить список предпочтений

    public class CustomListPreference extends ListPreference
    {
        Context mContext;
    
        public CustomListPreference(Context context, AttributeSet attrs)
        {
            super(context, attrs);
            mContext = context;
        }
    }
    
  2. Переопределите onPrepareDialogBuilder и замените mBuilder в DialogPreference на ProxyBuilder:

    @Override
    protected void onPrepareDialogBuilder(android.app.AlertDialog.Builder builder){
        super.onPrepareDialogBuilder(builder);
    
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.FROYO) {
            return;
        }
    
        // Inject Builder Proxy for intercepting of getView.
        try {
            Field privateBuilderField =
                DialogPreference.class.getDeclaredField("mBuilder");
            privateBuilderField.setAccessible(true);
    
            privateBuilderField.set(this, new ProxyBuilder(mContext, (android.app.AlertDialog.Builder)privateBuilderField.get(this)));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    
  3. Обработка getView в ProxyBuilder->AlertDialog->onShow->getListView->Adapter

    private class ProxyBuilder extends android.app.AlertDialog.Builder{
    
        android.app.AlertDialog.Builder mBuilder;
    
        private ProxyBuilder(Context context, AlertDialog.Builder builder) {
            super(context);
            mBuilder = builder;
        }
    
    
        @TargetApi(Build.VERSION_CODES.FROYO)
        @Override
        public AlertDialog create() {
            AlertDialog alertDialog = mBuilder.create();
            alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
                @Override
                public void onShow(DialogInterface dialog) {
                    ListView listView = ((AlertDialog)dialog).getListView();
                    final ListAdapter originalAdapter = listView.getAdapter();
    
                    listView.setAdapter(new ListAdapter(){
                        @Override
                        public int getCount() {
                            return originalAdapter.getCount();
                        }
    
                        @Override
                        public Object getItem(int id) {
                            return originalAdapter.getItem(id);
                        }
    
                        @Override
                        public long getItemId(int id) {
                            return originalAdapter.getItemId(id);
                        }
    
                        @Override
                        public int getItemViewType(int id) {
                            return originalAdapter.getItemViewType(id);
                        }
    
                        @Override
                        public View getView(int position, View convertView, ViewGroup parent) {
                            View view = originalAdapter.getView(position, convertView, parent);
                            TextView textView = (TextView)view;
                            textView.setTextColor(Color.RED);
                            return view;
                        }
    
                        @Override
                        public int getViewTypeCount() {
                            return originalAdapter.getViewTypeCount();
                        }
    
                        @Override
                        public boolean hasStableIds() {
                            return originalAdapter.hasStableIds();
                        }
    
                        @Override
                        public boolean isEmpty() {
                            return originalAdapter.isEmpty();
                        }
    
                        @Override
                        public void registerDataSetObserver(DataSetObserver observer) {
                            originalAdapter.registerDataSetObserver(observer);
    
                        }
    
                        @Override
                        public void unregisterDataSetObserver(DataSetObserver observer) {
                            originalAdapter.unregisterDataSetObserver(observer);
    
                        }
    
                        @Override
                        public boolean areAllItemsEnabled() {
                            return originalAdapter.areAllItemsEnabled();
                        }
    
                        @Override
                        public boolean isEnabled(int position) {
                            return originalAdapter.isEnabled(position);
                        }
    
                    });
                }
            });
            return alertDialog;
        }
    }
    
person galex    schedule 24.11.2013

Это сработало для меня, но не сработало, если список не помещается на экране (и требует прокрутки). Мне потребовалось очень много времени, чтобы найти решение (но я, наконец, нашел).

Во-первых, проблема: Как описано здесь: getView вызывается с неправильной позицией при быстрой прокрутке, вы получите непредсказуемое поведение, когда используете прослушиватель onclick в:

public View getView(final int position, View convertView, ViewGroup parent)

В моем случае событие onClick будет храниться в памяти и будет выполняться, когда пользователь попытается прокрутить (слегка).

А теперь решение: поместите прослушиватель onClick в основной класс (по крайней мере, это сработало для меня):

public class CustomListPreference extends ListPreference {

// Other code (see above)
@Override
protected void onPrepareDialogBuilder(Builder builder)
{
    builder.setPositiveButton(null, null);

    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 position)
        {
            // Code here, using position to indicate the row that was clicked...
            dialog.dismiss();
        }
    });

}

Потратьте на это слишком много времени, так что надеюсь, что это кому-то поможет :)

В общем, я очень доволен этим примером кода! (используйте его как палитру цветов).

P.S. Если вам нравится этот пост, пожалуйста, проголосуйте за полезность. Спасибо!

person EddyBee    schedule 10.10.2014