Как добавить иконки в настройки - PullRequest
24 голосов
/ 23 апреля 2011

Я создаю приложение, расширяющее PreferenceActivity, и хочу добавить значок для каждого предпочтения.

Я прочитал похожий вопрос, и это ответ с большей репутацией:

CommonsWare Say:

Приложение «Настройки» использует собственный подкласс PreferenceScreen, чтобы иметь значок - IconPreferenceScreen.Это 51 строка кода, включая комментарии, хотя он также требует некоторых пользовательских атрибутов.Самый простой вариант - клонировать все это в ваш проект, даже если вам это не нравится.

Но я не могу заставить его работать.Сейчас я клонировал класс IconPreferenceScreen в мой проект.И я не знаю, что мне делать после этого.Я пытаюсь сделать новый IconPreferenceScreen Я не могу заставить его работать ..

    IconPreferenceScreen test = new IconPreferenceScreen();
    test.setIcon(icon);

Ответы [ 9 ]

37 голосов
/ 28 мая 2013

Сегодня вы можете просто использовать android: icon attr, доступный с API 11:)

19 голосов
/ 26 апреля 2011

После многих испытаний и множества ошибок я смог получить это!

Я должен был сделать это:

1 - Клонировать класс IconPreferenceScreen из собственного приложения настроек Android (спасибо CommonWare)

2 - Клонируйте файл макета preference_icon.xml из приложения настроек Android.

3 - Объявление стиля IconPreferenceScreen в файле attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="IconPreferenceScreen">
         <attr name="icon" format="reference" />
    </declare-styleable>
</resources>

4 - Объявите экран IconPreferenceScreen в файле preference.xml:

<com.app.example.IconPreferenceScreen 
                android:title="IconPreferenceScreen Title"
                android:summary="IconPreferenceScreen Summary"
                android:key="key1" />

5 - Наконец, установите значок для предпочтения в классе предпочтений:

addPreferencesFromResource(R.xml.example);
IconPreferenceScreen test = (IconPreferenceScreen) findPreference("key1");
Resources res = getResources();
Drawable icon = res.getDrawable(R.drawable.icon1);
test.setIcon(icono1);

Еще раз спасибо CommonsWare за то, что сказали мне, с чего начать, и за его объяснение.

Это клонированный класс IconPreferenceScreen:

package com.app.example;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.preference.Preference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;

public class IconPreferenceScreen extends Preference {

    private Drawable mIcon;

    public IconPreferenceScreen(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public IconPreferenceScreen(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setLayoutResource(R.layout.preference_icon);
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.IconPreferenceScreen, defStyle, 0);
        mIcon = a.getDrawable(R.styleable.IconPreferenceScreen_icon);
    }

    @Override
    public void onBindView(View view) {
        super.onBindView(view);
        ImageView imageView = (ImageView) view.findViewById(R.id.icon);
        if (imageView != null && mIcon != null) {
            imageView.setImageDrawable(mIcon);
        }
    }

    public void setIcon(Drawable icon) {
        if ((icon == null && mIcon != null) || (icon != null && !icon.equals(mIcon))) {
            mIcon = icon;
            notifyChanged();
        }
    }

    public Drawable getIcon() {
        return mIcon;
    }
}

И это клонированный макет preference_icon.xml:

<LinearLayout android:id="@+android:id/iconpref"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical" 
    android:paddingRight="?android:attr/scrollbarSize">
    <ImageView android:id="@+id/icon" 
    android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:layout_marginLeft="6dip"
        android:layout_marginRight="6dip" 
        android:layout_gravity="center" />
    <RelativeLayout android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:layout_marginLeft="2dip"
        android:layout_marginRight="6dip" 
        android:layout_marginTop="6dip"
        android:layout_marginBottom="6dip" 
        android:layout_weight="1">
        <TextView android:id="@+android:id/title"
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:singleLine="true" 
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:ellipsize="marquee" 
            android:fadingEdge="horizontal" />
        <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>
</LinearLayout>
11 голосов
/ 25 октября 2011

Лучший и самый простой способ добиться того, чего вы хотите, - это сделать иконку иконкой из 9 патчей с правой границей в качестве растягиваемой области.

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

Вы создаете класс MyEditTextPreference, который расширяет EditTextPreference, и переопределяете метод getView, добавляя значок 9-патчей в качестве фонового ресурса.

Вот пример кода, которыйработает:

public class MyEditTextPreference extends EditTextPreference {

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

    @Override
    public View getView(View convertView, ViewGroup parent) {
        View view = super.getView(convertView, parent);
        view.setBackgroundResource(R.drawable.my_icon);
        return view;
    }
}

Поскольку значок представляет собой 9-патч, значок будет растягивать прозрачную часть до правого конца ячейки, помещая значок с левой стороны.

Этоочень чистое решение вашей проблемы.

5 голосов
/ 08 мая 2017

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

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
        android:title="@string/pref_profil"
        android:icon="@drawable/profile" // it wont show
        android:key="pref_key_storage_settings">

        <EditTextPreference
            android:key="edit_text_preference_1"
            android:selectAllOnFocus="true"
            android:singleLine="true"
            android:icon="@drawable/profile"
            android:title="Edit text preference" />

        <Preference
            android:key="pref_key_sms_delete_limit"
            android:summary="HELLO2"
            android:title="HELLO" />
    </PreferenceCategory>

</PreferenceScreen>

результат:

enter image description here

1 голос
/ 09 сентября 2011

Спасибо:

У меня сработало следующее:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="YOUR.PACKAGE.NAME">
    <application
        android:label="@string/app_name"
        android:icon="@drawable/icon">
        <activity
            android:name="AndroidMain"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

res / values ​​/ strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <string name="app_name">YOUR_APP_NAME</string>
    <string name="about">About</string>
</resources>

res / values ​​/ attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="IconPreference">
        <attr name="icon" format="reference" />
    </declare-styleable>
</resources>

res / layout / main.xml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:settings="http://schemas.android.com/apk/res/YOUR.PACKAGE.NAME"
    >
    <PreferenceCategory
        android:title="Main"
        android:key="mainPrefCat">
        <YOUR.PACKAGE.NAME.IconPreference
                android:title="Exit"
                android:summary="Quit the app."
                settings:icon="@drawable/YOUR_ICON"
                android:key="quitPref">
        </YOUR.PACKAGE.NAME.IconPreference>
    </PreferenceCategory>
</PreferenceScreen>

res / layout / preference_icon.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+android:id/widget_frame"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:paddingRight="?android:attr/scrollbarSize">
    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="6dip"
        android:layout_marginRight="6dip"
        android:layout_gravity="center" />
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="2dip"
        android:layout_marginRight="6dip"
        android:layout_marginTop="6dip"
        android:layout_marginBottom="6dip"
        android:layout_weight="1">
        <TextView android:id="@+android:id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal" />
        <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>
</LinearLayout>

Значки подходящего размера в:

res/drawable-hdpi/YOUR_ICON.png
res/drawable-mdpi/YOUR_ICON.png
res/drawable-ldpi/YOUR_ICON.png

AndroidMain.scala:

class AndroidMain extends PreferenceActivity {
  override def onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)
    addPreferencesFromResource(R.layout.main)
  }
}

IconPreference.scala:

class IconPreference(context: Context, attrs: AttributeSet, defStyle: Int) extends Preference(context, attrs, defStyle) {
    def this(context: Context, attrs: AttributeSet) = this(context, attrs, 0)

    setLayoutResource(R.layout.preference_icon);
    val a: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.IconPreference, defStyle, 0);
    val _icon: Drawable = a.getDrawable(R.styleable.IconPreference_icon);

    override def onBindView(view: View) {
        super.onBindView(view)
        val imageView: ImageView = view.findViewById(R.id.icon).asInstanceOf[ImageView]
        if (imageView != null && _icon != null) {
            imageView.setImageDrawable(_icon);
        }
    }
}
1 голос
/ 23 апреля 2011

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

Это не PreferenceActivity.

Как я могу добавить значок на PreferenceScreen?

Вам будет проще создать собственное действие, которое сохранит настройки.

Лично я бы просто пропустил значок и использовал обычную систему PreferenceScreen и PreferenceActivity.

0 голосов
/ 23 января 2017

Когда вам нужен список предпочтений с {text and icon}, вы можете взглянуть на этот список предпочтений с иконками

0 голосов
/ 03 апреля 2014

Для «нормального» ответа вы можете использовать метод 9-patch, описанный Henrique Rocha, или использовать следующее:

Создайте новый класс Preference, который расширяет EditTextPreference, и разрешите ему переопределитьonCreateView.

@Override
protected View onCreateView(ViewGroup parent)
{
    View v = LayoutInflater.from(getContext()).inflate(R.layout.iconpreference, null);

    return v;
}

Создайте новый макет XML с именем iconpreference, и в этом XML вы можете разрешить ему включать стандартный макет предпочтений.Вы можете настроить его так, как хотите.Простой пример:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <ImageView android:layout_width="48dp"
        android:layout_height="48dp"
        android:src="@drawable/checkmark_black"/>

    <include layout="@layout/preference_holo" />

</LinearLayout>

Вот и все!

0 голосов
/ 05 июля 2012

Попробуйте это:

PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);
PreferenceScreen ps= getPreferenceManager().createPreferenceScreen(this);
ps.setKey("ps");
ps.setLayoutResource(R.layout.your_layout);
root.addPreference(ps);
...