Tôi đã tìm kiếm thông qua và thông qua khắp nơi trên web, và không thể tìm thấy một cách để đạt được điều này. Câu trả lời ở trên không giúp tôi. Tôi thấy toàn bộ phương pháp "ArrayAdapter" rất không trực quan, vô ích và khó thực hiện. Cuối cùng, tôi thực sự đã phải xem xét bên trong mã nguồn cho "ListPreference", để xem những gì họ đã làm ở đó, và tìm ra cách để ghi đè lên hành vi mặc định một cách sạch sẽ và hiệu quả.
Tôi đang chia sẻ giải pháp của mình bên dưới. Tôi đã tạo lớp "SelectiveListPreference" để kế thừa hành vi của "ListPreference", nhưng thêm một nút tích cực, và ngăn chặn đóng khi một tùy chọn được nhấn. Ngoài ra còn có một thuộc tính xml mới để xác định các tùy chọn có sẵn trong phiên bản miễn phí.
Bí quyết của tôi không phải là gọi phiên bản của OnPrepareDialogBuilder của ListPreference, mà thay vào đó, thực hiện của riêng tôi, với trình xử lý nhấp chuột tùy chỉnh. Tôi không phải viết mã của riêng tôi để duy trì giá trị đã chọn, vì tôi đã sử dụng mã của ListPreference (đó là lý do tại sao tôi đã mở rộng "ListPreference" chứ không phải "Tùy chọn").
Trình xử lý tìm kiếm tài nguyên boolean "free_version" và nếu đúng, nó chỉ cho phép các tùy chọn được chỉ định trong thuộc tính xml "entry_values_free". Nếu "free_version" là sai, tất cả các tùy chọn đều được cho phép. Ngoài ra còn có một phương pháp trống cho người kế thừa, nếu một cái gì đó sẽ xảy ra khi một tùy chọn được chọn.
Thưởng thức,
Tal
public class SelectiveListPreference extends ListPreference
{
private int mSelectedIndex;
private Collection<CharSequence> mEntryValuesFree;
private Boolean mFreeVersion;
public SelectiveListPreference(Context context)
{
super(context);
}
//CTOR: load members - mEntryValuesFree & mFreeVersion
public SelectiveListPreference(Context context, AttributeSet attrs)
{
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.SelectiveListPreference);
try
{
CharSequence[] entryValuesFree = a
.getTextArray(R.styleable.SelectiveListPreference_entryValuesFree);
mEntryValuesFree = new ArrayList<CharSequence>(
Arrays.asList(entryValuesFree));
}
finally
{
a.recycle();
}
Resources resources = context.getResources();
mFreeVersion = resources.getBoolean(R.bool.free_version);
}
//override ListPreference's implementation - make our own dialog with custom click handler, keep the original selected index
@Override
protected void onPrepareDialogBuilder(android.app.AlertDialog.Builder builder)
{
CharSequence[] values = this.getEntries();
mSelectedIndex = this.findIndexOfValue(this.getValue());
builder.setSingleChoiceItems(values, mSelectedIndex, mClickListener)
.setPositiveButton(android.R.string.ok, mClickListener)
.setNegativeButton(android.R.string.cancel, mClickListener);
};
//empty method for inheritors
protected void onChoiceClick(String clickedValue)
{
}
//our click handler
OnClickListener mClickListener = new OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
if (which >= 0)//if which is zero or greater, one of the options was clicked
{
String clickedValue = (String) SelectiveListPreference.this
.getEntryValues()[which]; //get the value
onChoiceClick(clickedValue);
Boolean isEnabled;
if (mFreeVersion) //free version - disable some of the options
{
isEnabled = (mEntryValuesFree != null && mEntryValuesFree
.contains(clickedValue));
}
else //paid version - all options are open
{
isEnabled = true;
}
AlertDialog alertDialog = (AlertDialog) dialog;
Button positiveButton = alertDialog
.getButton(AlertDialog.BUTTON_POSITIVE);
positiveButton.setEnabled(isEnabled);
mSelectedIndex = which;//update current selected index
}
else //if which is a negative number, one of the buttons (positive or negative) was pressed.
{
if (which == DialogInterface.BUTTON_POSITIVE) //if the positive button was pressed, persist the value.
{
SelectiveListPreference.this.setValueIndex(mSelectedIndex);
SelectiveListPreference.this.onClick(dialog,
DialogInterface.BUTTON_POSITIVE);
}
dialog.dismiss(); //close the dialog
}
}
};
}
EDIT: chúng ta cũng cần phải ghi đè lên các thiết kế chức onDialogClosed từ ListPreference (và không làm gì cả), nếu không, mọi thứ có giá trị không được tồn.Địa chỉ:
protected void onDialogClosed(boolean positiveResult) {}
Không thể giải quyết phương thức getDialog(). – t0m