AndroidX - IconPicker 首选项(或自定义列表首选项)

问题描述 投票:0回答:1

多年来我一直在使用一个很好的 IconPickerPreference 就像这段代码中的

旧的 android.preference 库已弃用。大约 4 年以来,Android 提供了新的 androidx.preference 库。

执行搜索并用 androidx.preference 替换旧的 android.preference 并不是示例图标选择器首选项的有效解决方案。

你有 IconPickerPreference 的实现吗?每行由一个名称和一个图标组成。

我在网上找了好久都没有找到好的解决方案。我希望你能帮忙。

类似的问题没有提供好的答案。

我为 android.preference 找到的最接近我需要的解决方案如下。

问题是 @Override onPrepareDialogBuilder 不在 androidx.preference.ListPreference 类中。

android
1个回答
0
投票
经过大量实验,我想出了这个解决方案。第一步是创建一个用于自定义首选项的解决方案。您可以在下面找到自定义列表首选项。

AndroidX 的自定义列表首选项。首选项:

import androidx.appcompat.app.AlertDialog; import androidx.preference.ListPreference; public class CustomListPreference extends ListPreference { CustomListPreferenceAdapter customListPreferenceAdapter = null; Context mContext; private LayoutInflater mInflater; CharSequence[] entries; CharSequence[] entryValues; ArrayList<RadioButton> rButtonList; SharedPreferences prefs; SharedPreferences.Editor editor; private String mValue; private AlertDialog mDialog; public CustomListPreference(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; mInflater = LayoutInflater.from(context); rButtonList = new ArrayList<>(); } @Override protected void onClick() { entries = getEntries(); entryValues = getEntryValues(); mValue = getValue(); AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); customListPreferenceAdapter = new CustomListPreferenceAdapter(R.layout.custom_list_preference_row); builder.setAdapter(customListPreferenceAdapter, null); mDialog = builder.create(); mDialog.show(); } private class CustomListPreferenceAdapter extends BaseAdapter { int layoutIndex = 0; public CustomListPreferenceAdapter( int layoutIndex) { this.layoutIndex = layoutIndex; } public int getCount() { return entries.length; } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(final int position, View convertView, ViewGroup parent) { View row = convertView; CustomHolder holder = null; if(row == null) { row = mInflater.inflate(this.layoutIndex, parent, false); holder = new CustomHolder(row, position); row.setTag(holder); row.setClickable(true); } return row; } class CustomHolder { private TextView text = null; private RadioButton rButton = null; CustomHolder(View row, int position) { text = (TextView)row.findViewById(R.id.custom_list_view_row_text_view); text.setText(entries[position]); rButton = (RadioButton)row.findViewById(R.id.custom_list_view_row_radio_button); rButton.setId(position); } } } }
在 PreferenceScreen 中我得到了选择的结果。

或者自定义图标选择器首选项。粗略版本如下。我激励你改进版本。

public class IconPickerPreference extends ListPreference { CustomListPreferenceAdapter customListPreferenceAdapter = null; Context mContext; View mView; private LayoutInflater mInflater; private Resources resources; private String selectedIconFile, defaultIconFile; private int currentIndex = 0; CharSequence[] entries; CharSequence[] entryValues; ArrayList<RadioButton> rButtonList; private List<IconItem> icons; private String mValue; private AlertDialog mDialog; public IconPickerPreference(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; mInflater = LayoutInflater.from(context); resources = context.getResources(); rButtonList = new ArrayList<>(); entries = getEntries(); entryValues = getEntryValues(); mValue = getValue(); icons = new ArrayList<IconItem>(); for (int i = 0; i < entries.length; i++) { IconItem item = new IconItem(entries[i], entryValues[i], ( i == currentIndex)); icons.add(item); } TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.attrs_icon, 0, 0); try { defaultIconFile = a.getString(R.styleable.attrs_icon_iconFile); } finally { a.recycle(); } setWidgetLayoutResource( R.layout.prefernce_list_with_icons); } @Override protected void onClick() { entries = getEntries(); entryValues = getEntryValues(); mValue = getValue(); AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); customListPreferenceAdapter = new CustomListPreferenceAdapter(R.layout.prefernce_row_with_icon, icons); builder.setAdapter(customListPreferenceAdapter, null); mDialog = builder.create(); mDialog.show(); } @Override public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); mView = holder.itemView; mValue = getValue(); IconItem selectedIcon = getIconByIndexValue( mValue, icons); TextView tvItitle = mView.findViewById( R.id.title); tvItitle.setText( getTitle()); ImageView iconImage = mView.findViewById( R.id.iconSelected); if( iconImage != null) { int identifier = mContext.getResources().getIdentifier( selectedIcon.file, "drawable", mContext.getPackageName()); iconImage.setBackgroundResource(identifier); iconImage.setTag(selectedIconFile); } } private IconItem getIconByIndexValue( String value, List<IconItem> icons) { IconItem defaultIcon = icons.get( 0); int index = Integer.parseInt( value); if( index < 0 || index >= icons.size()) { return defaultIcon; } return icons.get( index); } void updatePreferenceIcon( int position) { setValue( "" + position); } private class CustomListPreferenceAdapter extends BaseAdapter { int layoutIndex = 0; List<IconItem> icons; public CustomListPreferenceAdapter( int layoutIndex, List<IconItem> icons) { this.layoutIndex = layoutIndex; this.icons = icons; } public int getCount() { return entries.length; } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(final int position, View convertView, ViewGroup parent) { View row = convertView; CustomHolder holder = null; if(row == null) { row = mInflater.inflate(this.layoutIndex, parent, false); holder = new CustomHolder(row, position); row.setTag(holder); row.setClickable(true); row.setOnClickListener( v -> { updatePreferenceIcon( position); mDialog.dismiss(); }); } return row; } class CustomHolder { private TextView text = null; private ImageView icon = null; CustomHolder(View row, int position) { text = (TextView)row.findViewById(R.id.pref_icon_title); text.setText(entries[position]); icon = row.findViewById(R.id.pref_icon_icon); mValue = getValue(); int identifier = mContext.getResources().getIdentifier( icons.get( position).file, "drawable", mContext.getPackageName()); icon.setBackgroundResource(identifier); icon.setTag(selectedIconFile); } } } 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; } } }
    
© www.soinside.com 2019 - 2024. All rights reserved.