I would like to change the RadioButton
that appears on ListPreference
dialog for a check mark or something different, or none, is there a simple way to do this?
-
I tried to find an attribute to change this in the ListPreference definition in xml, also programatically, but I couldn't find any. Probably the only way to do this would be by creating a custom ListPreference... I tried this without success, but I would like to avoid this if there is another way.– Esthon MedeirosCommented Jan 18, 2013 at 12:18
-
Hi @Matt Taylor, have you a clue about this, that helps me to answer my question? As I put bellow and in my question, I am looking for a simple way to do this, avoiding create a custom ListPreference. I did a lot of research and didn't find an attribute or parameter for this. But if there's no other way, I will evaluate whether it is worth to create a custom class.– Esthon MedeirosCommented Jan 18, 2013 at 15:16
-
I've had a look, and it doesn't appear possible with the current setup of the ListPreference, but I've found a blog that looks promising, but I haven't had time to read through a lot of it. It looks like it should provide what you need.– Matt TaylorCommented Jan 18, 2013 at 15:31
-
@Matt Taylor, I already saw the link you put before, it doesn't answer my question. Also I don't agree with you that my question is useless. I think it is an important question. Also, the fact I didn't put the effort I did before to put this question doesn't prove that I didn't take it, so, I ask you to reconsider and revert your downgrade vote. Also, now, I think I know the answer of my question: there is no simple way (attribute, etc) to change the radio bottom of ListPreference, so to do this I would need to create a custom class. BTW, I took another approach and already solved my problem.– Esthon MedeirosCommented Jan 20, 2013 at 21:36
-
I'm glad that you solved your problem, but I'm standing by my downvote. Whether your did the research or not, you didn't show that you did. You didn't say what you tried, you didn't say what you'd done. I don't dispute the usefulness of your question in that people want to do it. I dispute the way in which you have asked it. Because you didn't say anything you did, I wasted some of my time in looking through the xml attributes to see if there was a way, I wasted my time looking for and reading through the blog which you had "already found". If you had elaborated, it would have saved me time– Matt TaylorCommented Jan 21, 2013 at 9:20
4 Answers
If you want to change the whole dialog, maybe to use a replacement dialog library like this material-dialogs package, you can use this replacement ListPreference
:
import com.afollestad.materialdialogs.MaterialDialog;
public class MaterialListPreference extends ListPreference {
private MaterialDialog.Builder mBuilder;
private Context context;
public MaterialListPreference(Context context) {
super(context);
this.context = context;
}
public MaterialListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
@Override
protected void showDialog(Bundle state) {
mBuilder = new MaterialDialog.Builder(context);
mBuilder.title(getTitle());
mBuilder.icon(getDialogIcon());
mBuilder.positiveText(null);
mBuilder.negativeText(getNegativeButtonText());
mBuilder.items(getEntries());
mBuilder.itemsCallback(new MaterialDialog.ListCallback() {
@Override
public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) {
onClick(null, DialogInterface.BUTTON_POSITIVE);
dialog.dismiss();
if (which >= 0 && getEntryValues() != null) {
String value = getEntryValues()[which].toString();
if (callChangeListener(value))
setValue(value);
}
}
});
final View contentView = onCreateDialogView();
if (contentView != null) {
onBindDialogView(contentView);
mBuilder.customView(contentView);
}
else
mBuilder.content(getDialogMessage());
mBuilder.show();
}
}
It doesn't do much, just the bare minimum to override the dialog display and selection callback parts. YMMV very slightly if you opt for a different dialog library but not too much, they tend to be more or less direct replacements for AlertDialog
.
-
Was looking up how to do this with the exact use-case being this library. You are awesome! Just FYI, if you want it to show a radio button, you can figure out the value and find its index in entryValues at the beginning of showDialog, then use itemsCallbackSingleChoice Commented Dec 14, 2014 at 15:26
-
Also note that although this technically works, Google no longer wants us to do this. The design guide (google.com/design/spec/components/menus.html#menus-simple-menus) calls for a simple menu rather than a new modal dialogs in these cases now. That can be solved similarly easily, I have a replacement
MenuPreference
as well now to use in these situations.– GáborCommented Dec 15, 2014 at 12:38 -
Would this be showing a dropdown spinner over the preference instead? Could you maybe share a code example of MenuPreference via gist? I'm very interested to see how that would look! Commented Dec 15, 2014 at 18:36
-
1No, a PopupMenu. It's very simple, see gist.github.com/deakjahn/b12f10e3951cf595664c.– GáborCommented Dec 15, 2014 at 18:47
-
you just saved my life....i was searching for last 3 days....n cant find any good solution....thanx a lot...– H RavalCommented Sep 6, 2016 at 9:08
After analyzing the source code of ListPreference
in AndroidX I came to the conclusion that the simplest way is to write a Preference
that inherits from ListPreference
but generates it's own AlertDialog
that you can customize in whatever way you want:
import android.app.AlertDialog
import android.content.Context
import android.util.AttributeSet
import androidx.preference.ListPreference
import com.my.app.R
class MyListPreference : ListPreference {
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(
context,
attrs,
defStyleAttr
)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context?) : super(context)
override fun onClick() {
AlertDialog.Builder(context).setSingleChoiceItems(R.array.app_language, getValueIndex())
{ dialog, index->
if(callChangeListener(entryValues[index].toString())){
setValueIndex(index)
}
dialog.dismiss()
}
.setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() }
.show()
}
private fun getValueIndex() = context.resources.getStringArray(R.array.app_language).indexOf(value)
}
That way you can use your own style, title, icon and whatever else you can configure on an AlertDialog
.
-
Any idea on how to add a custom view holder? In my specific case, I'd like to replace the text with images Commented Nov 11, 2020 at 15:33
Try the following links hope it may help you out
-
Thanks a lot for your comments and very good links. I studied a lot the developer link and the example2 before I put this question and they don't answer my question. Or are you saying there is no simple way to change this, unless I create a custom ListPreference? This is what I would like to avoid, because I would like to keep it very simple. I just check example3 and 4, although they are very interesting they are related to create a custom class, also I should use them as a base to develop my solution, as they do not show how to change the radio button in the ListPreference dialog. Commented Jan 18, 2013 at 15:09
-
Not that terribly complicated, just grab the original source of
ListPreference.java
(Google for it, links come and go) and modify it to use your own dialog library. The original one usesAlertDialog
but there any many more similar libraries, for example for the new, material design.– GáborCommented Dec 11, 2014 at 12:51 -
if you want java code. try to following code.
public class SearchEngineListPreference extends ListPreference {
private Context mContext;
public SearchEngineListPreference(Context context) {
super(context);
mContext = context;
}
public SearchEngineListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
@SuppressWarnings("New API")
public SearchEngineListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
}
@SuppressWarnings("New API")
public SearchEngineListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mContext = context;
}
@Override
protected void onClick() {
AlertDialog.Builder ab = new AlertDialog.Builder(mContext);
ab.setCancelable(true);
ab.setTitle(getTitle());
String value = getValue();
ab.setSingleChoiceItems(R.array.setting_entries_search_engine,
findIndexOfValue(value),
(dialog, index) -> {
CharSequence[] entryValues = getEntryValues();
if (callChangeListener(entryValues[index].toString())){
setValueIndex(index);
}
dialog.dismiss();
}).setNeutralButton(mContext.getString(R.string.dialog_button_custom),
(dialog, whichButton) -> {
dialog.dismiss();
showEditDialog();
}).setNegativeButton(mContext.getString(R.string.dialog_button_negative),
(dialog, whichButton) -> {
dialog.dismiss();
});
ab.show();
}
private void showEditDialog() {
.......
}