Как установить значок в элементе ListPreference в Android

Я хочу установить значок в ListPreference элементах в android.

Что написать в ListPreference или куда написать, чтобы установить иконку элементов списка?


person viren jaru    schedule 26.08.2015    source источник


Ответы (2)


Вам нужно использовать специальный макет для вашего ListPreference.

eg:

<android.preference.ListPreference
                android:layout="@layout/your_custom_layout"
                 ....
/>

И добавьте то, что вы хотите, в свой собственный макет.

eg:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:paddingRight="?android:attr/scrollbarSize">

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_margin="@dimen/preferences_layout_margin">

        <ImageView android:id="@+id/yourIconId"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true" /> <!-- here i've added an ImageView for icon -->

        <TextView android:id="@android:id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal"
            android:layout_toRightOf="@+id/iconImageView"
            android:layout_marginLeft="@dimen/preferences_icon_margin" />

        <TextView android:id="@android:id/summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@android:id/title"
            android:layout_alignLeft="@android:id/title"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:maxLines="2" />

    </RelativeLayout>
    <!-- Preference should place its actual preference widget here. -->
    <LinearLayout android:id="@android:id/widget_frame"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:gravity="center_vertical"
        android:orientation="vertical" />

</LinearLayout>
person Rami    schedule 26.08.2015
comment
не могли бы вы дать мне демонстрационную программу для этого - person viren jaru; 26.08.2015
comment
Учебное пособие можно найти здесь: lucazanini.eu/2014/android/display- настройки значков - person Rami; 26.08.2015
comment
Я пробовал ту же программу, но она выдает такую ​​​​ошибку: - person viren jaru; 26.08.2015
comment
java.lang.NullPointerException: попытка вызвать виртуальный метод «void android.widget.ImageView.setImageResource(int)» для нулевой ссылки на объект в com.example.virenjaru.myapplication1.IconPickerPreference.updateIcon(IconPickerPreference.java:234) в com .example.virenjaru.myapplication1.IconPickerPreference.onBindView(IconPickerPreference.java:161) - person viren jaru; 26.08.2015
comment
@Override protected void onBindView (представление) { super.onBindView (представление); selectedIconFile = предпочтения.getString (resources.getString (R.string.custom_icon_key), defaultIconFile); icon = (ImageView) view.findViewById(R.id.iconSelected); значок обновления(); сводка = (TextView) view.findViewById(android.R.id.summary); summary.setText (getEntry (selectedIconFile)); } - person viren jaru; 26.08.2015
comment
private void updateIcon() { идентификатор int = resources.getIdentifier (selectedIconFile, drawable, context.getPackageName()); icon.setImageResource(идентификатор); icon.setTag(выбранныйIconFile); } - person viren jaru; 26.08.2015
comment
я не знаю, почему объект значка имеет значение null - person viren jaru; 26.08.2015
comment
Проверьте, совпадает ли идентификатор значка с идентификатором в методе findViewById(). - person Rami; 26.08.2015

Если вам нужно многократное использование предпочтения списка с текстами/значками, вы можете использовать это решение.

Эта версия во многом основана на хорошей версии LucaZanini. . Я внес некоторые незначительные изменения в версию, поэтому она зависит только от собственных атрибутов предпочтений. Таким образом, вы можете использовать их несколько раз. Пожалуйста, обратитесь к его учебнику.

@Лука - большое спасибо!

Мелкие изменения только:

  • IconPickerPreference.java, см. ниже.
  • Вам не нужна ссылка на файл strings.xml. Значение по умолчанию, установленное в начале, равно "0".
  • Вы можете улучшить эту версию, используя целое число для currentIndex, а не строку.

IconPickerPreference:

// @Based on the nice version of LucaZanini. Thank you!
public class IconPickerPreference extends ListPreference {
    private int currentIndex = 0;

    private class CustomListPreferenceAdapter extends ArrayAdapter<IconItem> {
        private Context context;
        private List<IconItem> icons;
        private int resource;

        public CustomListPreferenceAdapter(Context context, int resource, List<IconItem> objects) {
            super(context, resource, objects);
            this.context = context;
            this.resource = resource;
            this.icons = objects;
        }

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

            ViewHolder holder;
            if (convertView == null) {
                LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(resource, parent, false);

                holder = new ViewHolder();
                holder.iconName = (TextView) convertView.findViewById(R.id.iconName);
                holder.iconImage = (ImageView) convertView.findViewById(R.id.iconImage);
                holder.radioButton = (RadioButton) convertView.findViewById(R.id.iconRadio);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            holder.iconName.setText(icons.get(position).name);

            int identifier = context.getResources().getIdentifier( icons.get(position).file, "drawable", context.getPackageName());
            holder.iconImage.setImageResource(identifier);
            holder.radioButton.setChecked(icons.get(position).isChecked);
            convertView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    ViewHolder holder = (ViewHolder) v.getTag();
                    for (int i = 0; i < icons.size(); i++) {
                        if (i == position) {
                            icons.get(i).isChecked = true;
                        } else {
                            icons.get(i).isChecked = false;
                        }
                    }
                    getDialog().dismiss();
                }
            });
            return convertView;
        }
    }

    private class IconItem {
        private String  file;
        private boolean isChecked;
        private String  name;

        public IconItem(CharSequence name, CharSequence file, boolean isChecked) {
            this(name.toString(), file.toString(), isChecked);
        }

        public IconItem(String name, String file, boolean isChecked) {
            this.name = name;
            this.file = file;
            this.isChecked = isChecked;
        }

    }

    private class ViewHolder {
        protected ImageView     iconImage;
        protected TextView      iconName;
        protected RadioButton   radioButton;
    }

    private Context context;
    private ImageView icon;

    private CharSequence[] iconFile;
    private CharSequence[] iconName;
    private List<IconItem> icons;
    private SharedPreferences preferences;
    private Resources resources;
    private String selectedIconFile, defaultIconFile;
    private TextView summary;

    public IconPickerPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        resources = context.getResources();
        preferences = PreferenceManager.getDefaultSharedPreferences(context);

        TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.attrs_icon, 0, 0);
        try {
            defaultIconFile = a.getString(R.styleable.attrs_icon_iconFile);
        } finally {
            a.recycle();
        }
    }

    @Override
    protected void onBindView(View view) {
        super.onBindView(view);

        CharSequence[] entries = getEntries();
        CharSequence[] values = getEntryValues();
        selectedIconFile = values[ currentIndex].toString();
        icon = (ImageView) view.findViewById(R.id.iconSelected);
        updateIcon();
        summary = (TextView) view.findViewById( R.id.preference_summary);
        summary.setText( entries[ currentIndex]);
    }

    @Override
    protected void onDialogClosed(boolean positiveResult) {
        super.onDialogClosed(positiveResult);
        if (icons != null) {
            for (int i = 0; i < iconName.length; i++) {
                IconItem item = icons.get(i);
                if (item.isChecked) {
                    persistString( "" + i);
                    currentIndex = i;
                    selectedIconFile = item.file;
                    updateIcon();
                    summary.setText(item.name);
                    break;
                }
            }
        }
    }

    @Override
    protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
        String number = "0";
        if (restorePersistedValue) {
            // Restore existing state
            number = this.getPersistedString( "0");
        } else {
            persistString( number);
        }
        try {
            currentIndex = Integer.parseInt(number);
        } catch( Exception e) {
            ; // skip any error, it will be corrected to 0
        }
    }

    @Override
    protected void onPrepareDialogBuilder(Builder builder) {   
        builder.setNegativeButton("Cancel", null);
        builder.setPositiveButton(null, null);
        iconName = getEntries();
        iconFile = getEntryValues();

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

        icons = new ArrayList<IconItem>();
        for (int i = 0; i < iconName.length; i++) {
            IconItem item = new IconItem(iconName[i], iconFile[i], ( i == currentIndex));
            icons.add(item);
        }
        CustomListPreferenceAdapter customListPreferenceAdapter = new CustomListPreferenceAdapter(
                context, R.layout.preference_list_icon_picker, icons);
        builder.setAdapter(customListPreferenceAdapter, null);
    }
    private void updateIcon() {
        int identifier = resources.getIdentifier( selectedIconFile, "drawable", context.getPackageName());
        icon.setImageResource(identifier);
        icon.setTag(selectedIconFile);
    }
}
person tm1701    schedule 23.01.2017
comment
Как перенести на него набор иконок? - person Dmitry; 29.08.2018
comment
1) Не удается разрешить символ preference_list_icon_picker 2) Невозможно разрешить метод setAdapter 3) В пример кода не включен импорт, что затрудняет определение используемой версии класса Builder. Еще одна большая проблема заключается в том, что оригинальный проект Луки Заниниса содержит множество устаревших классов. Поэтому очень рискованно использовать такое решение в продакшене. Это, вероятно, вызовет много сбоев. Помогите, пожалуйста, найти современный способ добавления иконок в ListPreference! Это сделало бы приложения намного более удобными для пользователя и более увлекательными в использовании. - person Mobile Visuals; 18.01.2020