Closed rala72 closed 7 months ago
It could be controlled by app:showSelectAllButton="true"
XML attribute.
Do you have a graphic design in mind?
not really for me a neutral button (on left) is enough which toggles all
Until then you can do this in your project.
Subclass XpMultiSelectListPreferecnceDialogFragment
and override onPrepareDialogBuilder
. Set the neutral button text and listener on the builder
parameter.
Have your fragment/activity implement OnPreferenceDisplayDialogCallback
.
@Override
public boolean onPreferenceDisplayDialog(@NonNull final PreferenceFragmentCompat caller, @NonNull final Preference pref) {
if (pref instanceof net.xpece.android.support.preference.MultiSelectListPreference) {
final FragmentManager fm = getSupportFragmentManager(); // Or getFragmentManager() in Fragment.
if (fm.findFragmentByTag("android.support.v7.preference.PreferenceFragment.DIALOG") == null) {
// Only show a dialog if we're not already showing any dialog.
final Fragment f = new YourModifiedDialogFragmentFromStep1(); // Replace the name.
final Bundle b = new Bundle(1);
b.putString("key", pref.getKey());
fragment.setArguments(b);
f.setTargetFragment(caller, 0);
f.show(fm, "android.support.v7.preference.PreferenceFragment.DIALOG");
return true;
}
}
return false;
}
I searched a bit why f.show
isn't working until I noticed it should be final DialogFragment f
.
update: fragment
has to be f
now I get this log:
FATAL EXCEPTION: main
Process: at.my.package, PID: 21722
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
at android.support.v7.preference.PreferenceDialogFragmentCompat.onCreate(PreferenceDialogFragmentCompat.java:87)
at net.xpece.android.support.preference.XpMultiSelectListPreferenceDialogFragment.onCreate(XpMultiSelectListPreferenceDialogFragment.java:103)
at android.support.v4.app.Fragment.performCreate(Fragment.java:2236)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1285)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1569)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1636)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2415)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2201)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2155)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2064)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:718)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6809)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Sorry, forgot about the preference key, check out the updated code
It works! =D Thank you very much ;)
Now I've only to figure out how to prevent dismissing the dialog on clicking this button...
Maybe I'll figure it out with sth like this from Stackoverflow
Oh yeah, that seems useful :D You can do that in onCreateDialog
.
And how to select/deselect the items is also missing. You'll have to
boolean mPreferenceChanged;
HashSet<String> mNewValues = new HashSet();
boolean[] mSelectedItems = new boolean[0];
These variables are package-private and you can access them without reflection if your subclass is in the same package.
The logic is best (and only) available in the source code to XpMultiSelectListPreferenceDialogFragment
.
For that you need to get the list and call setItemChecked
with [0..mSelectedItems.length -1].
How you'll get the list? Old text removed. Turns out AlertDialog
has a getListView()
method. So just cast the dialog and get it.
to un/-/select all entries I've already this code in my custom MyXpMultiSelectListPreferenceDialogFragment
(I use retro-lambda):
@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
builder.setNeutralButton(R.string.pref_ignoredSubjects_toggleAll, (dialog, which) -> {
MultiSelectListPreference preference = getMultiSelectListPreference();
boolean allSelected = true;
for (CharSequence charSequence : preference.getEntryValues()) {
if (!preference.getValues().contains(String.valueOf(charSequence))) {
allSelected = false;
break;
}
}
if (!allSelected) {
Set<String> values = Stream.of(preference.getEntryValues()).map(String::valueOf).collect(Collectors.toSet());
preference.setValues(values);
} else preference.setValues(new TreeSet<>());
});
}
Here's my current WIP:
What's missing:
closed because of inactivity
It would be nice if there is a neutral button to un-/select all entries.