web-dev-qa-db-fra.com

Comment ajouter des icônes à Préférence

Je crée une application qui étend PreferenceActivity et je souhaite ajouter une icône à chaque préférence.

J'ai lu une question similaire, et voici la réponse avec plus de réputation:

CommonsWare Dites:

L'application Paramètres utilise une sous-classe PreferenceScreen personnalisée et privée pour avoir l'icône - IconPreferenceScreen. Il s'agit de 51 lignes de code, y compris les commentaires, bien que certains attributs personnalisés soient également requis. L'option la plus simple est de tout dupliquer dans votre projet, même si cela ne vous plaît pas.

Mais je ne peux pas le faire fonctionner. Pour l'instant, j'ai cloné la classe IconPreferenceScreen dans mon projet. Et je ne sais pas ce que je dois faire après cela. J'essaie de créer un nouvel IconPreferenceScreen. Je ne peux pas le faire fonctionner.

    IconPreferenceScreen test = new IconPreferenceScreen();
    test.setIcon(icon);
22
Tony Ceralva

Après de nombreux tests et de nombreuses erreurs, j'ai pu l'obtenir!

Je devais le faire:

1 - / Clonez la classe IconPreferenceScreen à partir de l'application native Android Settings (grâce à CommonWare)

2 - Clonez le fichier de mise en page preference_icon.xml à partir de l'application Paramètres Android.

3 - / Déclarez le IconPreferenceScreen styleable dans le fichier attrs.xml:

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

4 - Déclarez IconPreferenceScreen dans le fichier preference.xml:

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

5 - Enfin, définissez l'icône de la préférence dans la classe de préférence:

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

Merci encore à CommonsWare pour m'avoir dit par où commencer et pour son explication.

Il s'agit de la classe IconPreferenceScreen clonée:

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

Et voici la disposition clonée 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>
18
Tony Ceralva

Aujourd'hui, vous pouvez simplement utiliser Android: icon attr disponible depuis API 11 :)

36
Vadim

Le moyen le plus simple et le plus simple d’atteindre ce que vous voulez est de faire de l’icône une icône de 9 patchs avec le bord droit comme zone extensible.

Supposons que vous avez un EditTextPreference que vous souhaitez ajouter une icône avant le titre et le résumé.

Vous créez une classe MyEditTextPreference qui étend EditTextPreference et substituez la méthode getView pour ajouter votre icône de 9 correctifs en tant que ressource d'arrière-plan.

Voici un exemple de code qui fonctionne:

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

Comme l’icône est un patch 9, l’icône étendra la partie transparente jusqu’à l’extrémité droite de la cellule, plaçant l’icône sur le côté gauche.

C'est une solution très propre à votre problème.

11
Henrique Rocha

bien trop tard, mais peut-être que cela peut aider le problème, c’est que vous pouvez ajouter une icône unique aux enfants d’une catégorie comme celle-ci: ce sont mes exemples de code. seule l'icône d'édition de texte est visible à l'écran.

<?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>

résultat:

 enter image description here

3
mehmet

Grâce à:

Ce qui suit a fonctionné pour moi:

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>

Icônes de taille appropriée sous:

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
W1M0R

Je crée une application dans laquelle PreferenceActivity est l'activité principale et je souhaite ajouter une icône à chaque préférence personnalisée. Comme cette image:

Ce n'est pas une PreferenceActivity.

Comment puis-je ajouter une icône à l'écran PreferenceScreen?

Il sera plus simple pour vous de créer votre propre activité qui consiste à enregistrer les préférences.

Personnellement, je sauterais simplement l'icône et utiliserais les systèmes PreferenceScreen et PreferenceActivity.

1
CommonsWare

Lorsque vous avez besoin d’une préférence de liste avec {texte et icône}, vous pouvez consulter cette liste de préférences avec icônes

0
tjm1706

Pour une réponse "saine", vous pouvez utiliser la méthode des 9 patchs décrite par Henrique Rocha ou utiliser les éléments suivants:

Créez une nouvelle classe de préférences qui étend EditTextPreference et laissez-la remplacer par onCreateView.

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

    return v;
}

Créez un nouveau XML de présentation appelé iconpreference. Dans ce XML, vous pouvez lui permettre d'inclure une présentation de préférence standard. Vous pouvez simplement la modifier comme vous le souhaitez. Exemple simple:

    <?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>

C'est tout!

0
JanCor