多年来我一直在使用一个很好的 IconPickerPreference 就像这段代码中的。
旧的 android.preference 库已弃用。大约 4 年以来,Android 提供了新的 androidx.preference 库。执行搜索并用 androidx.preference 替换旧的 android.preference 并不是示例图标选择器首选项的有效解决方案。
你有 IconPickerPreference 的实现吗?每行由一个名称和一个图标组成。
我在网上找了好久都没有找到好的解决方案。我希望你能帮忙。
类似的问题没有提供好的答案。
我为 android.preference 找到的最接近我需要的解决方案如下。问题是 @Override onPrepareDialogBuilder 不在 androidx.preference.ListPreference 类中。
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;
}
}
}