【问题标题】:How to set icon in ListPreference's item in android如何在Android的ListPreference项目中设置图标
【发布时间】:2015-08-26 12:09:01
【问题描述】:

我想在android的ListPreference项目中设置图标。

ListPreference写什么或者在哪里写来设置列表项图标?

【问题讨论】:

    标签: android image icons listpreference


    【解决方案1】:

    当您需要多次使用带有文本/图标的列表首选项时,您可以使用此解决方案。

    这个版本很大程度上基于nice version of LucaZanini。我对版本做了一些小改动,所以它只依赖于自己的偏好属性。通过这种方式,您可以多次使用它们。请参考他的教程。

    @Luca - 非常感谢!

    小改动只有:

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

    【讨论】:

    • 如何传输设置的图标?
    • 1) 无法解析符号preference_list_icon_picker 2) 无法解析方法setAdapter 3) 示例代码中不包含导入,这使得很难知道使用的是哪个版本的Builder 类。另一个大问题是 Luca Zainis 的原始项目包含大量已弃用的类。所以在生产中使用这样的解决方案是非常冒险的。它可能会导致很多崩溃。请帮助我找到一种将图标添加到 ListPreference 的现代方法!这将使应用程序更加用户友好,使用起来更有趣。
    【解决方案2】:

    您需要为ListPreference 使用自定义布局。

    例如:

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

    并将您想要的内容添加到您的自定义布局中。

    例如:

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

    【讨论】:

    • 你能给我这个演示程序吗
    • 你可以在这里找到教程:lucazanini.eu/2014/android/display-icon-preferences
    • 我尝试了相同的程序,但它给了我这样的错误:
    • java.lang.NullPointerException: 尝试在 com.example.virenjaru.myapplication1.IconPickerPreference.updateIcon( IconPickerPreference.java:234) 在 com.example.virenjaru.myapplication1.IconPickerPreference.onBindView(IconPickerPreference.java:161)
    • @Override protected void onBindView(View view) { super.onBindView(view); selectedIconFile = preferences.getString(resources.getString(R.string.custom_icon_key), defaultIconFile);图标 = (ImageView) view.findViewById(R.id.iconSelected);更新图标();摘要 = (TextView) view.findViewById(android.R.id.summary); summary.setText(getEntry(selectedIconFile)); }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    • 1970-01-01
    • 2011-05-20
    • 2018-05-29
    • 2017-02-04
    • 2011-07-09
    • 1970-01-01
    相关资源
    最近更新 更多