I'm making an app that extends the PreferenceActivity and I want to add an icon to each Preference.
I read a similar question, and this is the answer with more reputation:
CommonsWare Say:
The Settings application uses a private custom PreferenceScreen subclass to have the icon -- IconPreferenceScreen. It is 51 lines of code, including the comments, though it also requires some custom attributes. The simplest option开发者_运维百科 is to clone all of that into your project, even though you do not like that.
But I can't make it work. For now I cloned the class IconPreferenceScreen to my project. And I don't know what I have to do after this. I'm trying to make a new IconPreferenceScreen I can't make it work..
IconPreferenceScreen test = new IconPreferenceScreen();
test.setIcon(icon);
Today you can just use android:icon
attr available since API 11 :)
After many tests and many mistakes I could get it!
I had to do this:
1 - Clone the class IconPreferenceScreen from the Android native Settings app (thanks CommonWare)
2 - Clone the layout file preference_icon.xml from the Android Settings app.
3 - Declare the IconPreferenceScreen styleable in the file attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="IconPreferenceScreen">
<attr name="icon" format="reference" />
</declare-styleable>
</resources>
4 - Declare the IconPreferenceScreen in the preference.xml file:
<com.app.example.IconPreferenceScreen
android:title="IconPreferenceScreen Title"
android:summary="IconPreferenceScreen Summary"
android:key="key1" />
5 - Finally set the icon for the preference, in the preference class:
addPreferencesFromResource(R.xml.example);
IconPreferenceScreen test = (IconPreferenceScreen) findPreference("key1");
Resources res = getResources();
Drawable icon = res.getDrawable(R.drawable.icon1);
test.setIcon(icono1);
Thanks again to CommonsWare for tell me where to start, and for his explanation.
This is the cloned IconPreferenceScreen class:
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;
}
}
And this is the cloned preference_icon.xml layout:
<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>
The best and easiest way to achieve what you want is to make the icon a 9-patch icon with the right border as the stretchable area.
Let's say you have an EditTextPreference that you want to add an icon before the title and summary.
You create a MyEditTextPreference class that extends EditTextPreference and override the getView method to add your 9-patch icon as the background resource.
Here is a sample code that works:
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;
}
}
Since the icon is a 9-patch, the icon will stretch the transparent part until the right end of the cell, placing the icon on the left side.
This is a very clean solution for your problem.
well too late but maybe it will helps somebody the problem is this you can add icon only child of a category such as this is my code samples. only edit text icon can be seen on the screen.
<?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>
result:
I'm making an app in that the PreferenceActivity is the main activity and I want to add an icon to each Custom Preference. Like this image:
That's not a PreferenceActivity
.
How I can add an icon to the PreferenceScreen?
It will be simpler for you to just create your own activity that happens to save preferences.
Personally, I would just skip the icon and use the regular PreferenceScreen
and PreferenceActivity
system.
Thanks to:
- The answer by @Tony_GPR
- https://github.com/CyanogenMod/android_packages_apps_Settings
- http://developer.android.com/guide/practices/ui_guidelines/icon_design.html
- http://developer.android.com/guide/practices/ui_guidelines/icon_design_list.html
- Scala
The following worked for me:
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>
Appropriately sized icons under:
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);
}
}
}
For a "sane" Answer, you can either use the 9-patch method as described by Henrique Rocha or you can use the following:
Create a new Preference class that extends EditTextPreference and let it Override the onCreateView.
@Override
protected View onCreateView(ViewGroup parent)
{
View v = LayoutInflater.from(getContext()).inflate(R.layout.iconpreference, null);
return v;
}
Create a new Layout XML called iconpreference and in this XML you can let it include a standard preference layout. You can basicly tweak it every way you want. Easy Example:
<?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>
Thats all!
When you need a listpreference with {text and icon} you can have a look at this listpreference with icons
Try this:
PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);
PreferenceScreen ps= getPreferenceManager().createPreferenceScreen(this);
ps.setKey("ps");
ps.setLayoutResource(R.layout.your_layout);
root.addPreference(ps);
精彩评论