Add MultiSelectBooleanPreference

This commit is contained in:
Chumva 2019-09-03 17:42:33 +03:00
parent 0cf05abbb9
commit 53b9043f41
8 changed files with 263 additions and 107 deletions

View file

@ -3,13 +3,13 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<Preference
android:key="personal_account"
android:layout="@layout/preference_with_descr"
android:persistent="false"
android:summary="@string/personal_account_descr"
android:title="@string/personal_account"
tools:icon="@drawable/ic_person" />
<!-- <Preference-->
<!-- android:key="personal_account"-->
<!-- android:layout="@layout/preference_with_descr"-->
<!-- android:persistent="false"-->
<!-- android:summary="@string/personal_account_descr"-->
<!-- android:title="@string/personal_account"-->
<!-- tools:icon="@drawable/ic_person" />-->
<Preference
android:key="global_settings"
@ -26,11 +26,11 @@
android:title="@string/application_profiles" />
<Preference
android:key="browse_map"
android:key="configure_profile_general"
android:layout="@layout/preference_with_descr"
android:persistent="false"
android:summary="@string/map_look_descr"
android:title="@string/rendering_value_browse_map_name"
android:title="@string/general_settings_2"
app:fragment="net.osmand.plus.settings.GeneralProfileSettingsFragment"
tools:icon="@drawable/ic_world_globe_dark" />
<Preference

View file

@ -127,7 +127,7 @@ import net.osmand.plus.search.QuickSearchDialogFragment;
import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchTab;
import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchType;
import net.osmand.plus.settings.BaseSettingsFragment;
import net.osmand.plus.settings.SettingsMainFragment;
import net.osmand.plus.settings.MainSettingsFragment;
import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint;
import net.osmand.plus.views.AnimateDraggingMapThread;
import net.osmand.plus.views.MapControlsLayer;
@ -2182,7 +2182,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
}
public void showSettings() {
SettingsMainFragment.showInstance(getSupportFragmentManager());
MainSettingsFragment.showInstance(getSupportFragmentManager());
}
private void hideContextMenu() {

View file

@ -40,6 +40,7 @@ import net.osmand.plus.activities.OsmandInAppPurchaseActivity;
import net.osmand.plus.profiles.AppProfileArrayAdapter;
import net.osmand.plus.profiles.ProfileDataObject;
import net.osmand.plus.settings.preferences.ListPreferenceEx;
import net.osmand.plus.settings.preferences.MultiSelectBooleanPreference;
import net.osmand.plus.settings.preferences.SwitchPreferenceEx;
import java.util.ArrayList;
@ -405,6 +406,11 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl
if (fragmentManager != null) {
EditTextPreferenceBottomSheet.showInstance(fragmentManager, preference.getKey(), this);
}
} else if (preference instanceof MultiSelectBooleanPreference) {
FragmentManager fragmentManager = getFragmentManager();
if (fragmentManager != null) {
MultiSelectPreferencesBottomSheet.showInstance(getFragmentManager(), preference.getKey(), this);
}
} else {
super.onDisplayPreferenceDialog(preference);
}

View file

@ -165,7 +165,7 @@ public class GeneralProfileSettingsFragment extends BaseSettingsFragment {
// PointDescription.formatToHumanString(ctx, PointDescription.UTM_FORMAT),
// PointDescription.formatToHumanString(ctx, PointDescription.OLC_FORMAT)
// });
// coordinatesFormat.setEntryValues(new Integer[] {
// coordinatesFormat.setPrefsIds(new Integer[] {
// PointDescription.FORMAT_DEGREES,
// PointDescription.FORMAT_MINUTES,
// PointDescription.FORMAT_SECONDS,

View file

@ -6,17 +6,12 @@ import android.support.v7.preference.Preference;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.profiles.SettingsProfileActivity;
import net.osmand.util.Algorithms;
import static net.osmand.plus.profiles.EditProfileFragment.MAP_CONFIG;
import static net.osmand.plus.profiles.EditProfileFragment.OPEN_CONFIG_ON_MAP;
import static net.osmand.plus.profiles.EditProfileFragment.SELECTED_ITEM;
public class MainSettingsFragment extends BaseSettingsFragment {
public class SettingsMainFragment extends BaseSettingsFragment {
public static final String TAG = "SettingsMainFragment";
public static final String TAG = "MainSettingsFragment";
@Override
protected int getPreferencesResId() {
@ -40,10 +35,7 @@ public class SettingsMainFragment extends BaseSettingsFragment {
@Override
protected void setupPreferences() {
Preference personalAccount = findPreference("personal_account");
Preference globalSettings = findPreference("global_settings");
personalAccount.setIcon(getContentIcon(R.drawable.ic_action_user));
globalSettings.setIcon(getContentIcon(R.drawable.ic_action_settings));
setupConfigureProfilePref();
@ -58,12 +50,23 @@ public class SettingsMainFragment extends BaseSettingsFragment {
}
private void setupBrowseMapPref() {
Preference browseMap = findPreference("browse_map");
browseMap.setIcon(getContentIcon(R.drawable.ic_world_globe_dark));
Intent intent = new Intent(getActivity(), MapActivity.class);
intent.putExtra(OPEN_CONFIG_ON_MAP, MAP_CONFIG);
intent.putExtra(SELECTED_ITEM, getSelectedAppMode().getStringKey());
browseMap.setIntent(intent);
ApplicationMode selectedMode = getSelectedAppMode();
int iconRes = selectedMode.getIconRes();
int iconColor = selectedMode.getIconColorInfo().getColor(isNightMode());
String title = selectedMode.toHumanString(getContext());
String profileType;
if (selectedMode.isCustomProfile()) {
profileType = String.format(getString(R.string.profile_type_descr_string), Algorithms.capitalizeFirstLetterAndLowercase(selectedMode.getParent().toHumanString(getContext())));
} else {
profileType = getString(R.string.profile_type_base_string);
}
Preference configureProfile = findPreference("configure_profile_general");
configureProfile.setIcon(getIcon(iconRes, iconColor));
configureProfile.setTitle(title);
configureProfile.setSummary(profileType);
}
private void setupConfigureProfilePref() {
@ -86,22 +89,12 @@ public class SettingsMainFragment extends BaseSettingsFragment {
configureProfile.setSummary(profileType);
}
@Override
public boolean onPreferenceClick(Preference preference) {
if (preference.getKey().equals("browse_map")) {
getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
return false;
}
return super.onPreferenceClick(preference);
}
public static boolean showInstance(FragmentManager fragmentManager) {
try {
SettingsMainFragment settingsMainFragment = new SettingsMainFragment();
MainSettingsFragment MainSettingsFragment = new MainSettingsFragment();
fragmentManager.beginTransaction()
.replace(R.id.fragmentContainer, settingsMainFragment, SettingsMainFragment.TAG)
.addToBackStack(SettingsMainFragment.TAG)
.replace(R.id.fragmentContainer, MainSettingsFragment, TAG)
.addToBackStack(TAG)
.commitAllowingStateLoss();
return true;
} catch (Exception e) {

View file

@ -4,79 +4,105 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.preference.DialogPreference;
import android.view.View;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.LongDescriptionItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
import net.osmand.plus.settings.preferences.MultiSelectBooleanPreference;
import net.osmand.util.Algorithms;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class MultiSelectPreferencesBottomSheet extends MenuBottomSheetDialogFragment {
public static final String TAG = MultiSelectPreferencesBottomSheet.class.getSimpleName();
private static final String TITLE_KEY = "title_key";
private static final String DESCRIPTION_KEY = "description_key";
private static final String PREFERENCES_PARAMETERS_KEY = "preferences_parameters_key";
private static final String PREFERENCE_ID = "preference_id";
private static final String PREFERENCES_IDS = "preferences_ids";
private static final String PREFERENCE_CHANGED = "preference_changed";
private static final String PREFERENCES_ENTRIES = "preferences_entries";
private static final String ENABLED_PREFERENCES_IDS = "enabled_preferences_ids";
private String title = "";
private String description = "";
private MultiSelectBooleanPreference multiSelectBooleanPreference;
private String[] vals = null;
private OsmandSettings.OsmandPreference<Boolean>[] prefs = null;
private boolean[] tempPrefs = null;
private String[] prefsIds;
private CharSequence[] entries;
private Set<String> enabledPrefs = new HashSet<>();
private boolean preferenceChanged;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
multiSelectBooleanPreference = getListPreference();
if (savedInstanceState == null) {
if (multiSelectBooleanPreference.getEntries() == null || multiSelectBooleanPreference.getPrefsIds() == null) {
throw new IllegalStateException("MultiSelectListPreference requires an entries array and an entryValues array.");
}
enabledPrefs.clear();
enabledPrefs.addAll(multiSelectBooleanPreference.getValues());
preferenceChanged = false;
entries = multiSelectBooleanPreference.getEntries();
prefsIds = multiSelectBooleanPreference.getPrefsIds();
} else {
enabledPrefs.clear();
enabledPrefs.addAll(savedInstanceState.getStringArrayList(ENABLED_PREFERENCES_IDS));
preferenceChanged = savedInstanceState.getBoolean(PREFERENCE_CHANGED, false);
entries = savedInstanceState.getCharSequenceArray(PREFERENCES_ENTRIES);
prefsIds = savedInstanceState.getStringArray(PREFERENCES_IDS);
}
}
@Override
public void createMenuItems(Bundle savedInstanceState) {
final OsmandApplication app = getMyApplication();
if (app == null) {
if (app == null || multiSelectBooleanPreference == null) {
return;
}
if (savedInstanceState != null) {
if (savedInstanceState.containsKey(TITLE_KEY)) {
title = savedInstanceState.getString(PREFERENCES_PARAMETERS_KEY);
}
if (savedInstanceState.containsKey(DESCRIPTION_KEY)) {
description = savedInstanceState.getString(PREFERENCES_PARAMETERS_KEY);
}
if (savedInstanceState.containsKey(PREFERENCES_PARAMETERS_KEY)) {
tempPrefs = savedInstanceState.getBooleanArray(PREFERENCES_PARAMETERS_KEY);
}
}
String title = multiSelectBooleanPreference.getDialogTitle().toString();
items.add(new TitleItem(title));
String description = multiSelectBooleanPreference.getDescription();
if (!Algorithms.isEmpty(description)) {
items.add(new LongDescriptionItem(description));
}
tempPrefs = new boolean[prefs.length];
for (int i = 0; i < entries.length; i++) {
String prefId = prefsIds[i];
for (int i = 0; i < prefs.length; i++) {
String title = vals[i];
boolean selected = prefs[i].get();
tempPrefs[i] = selected;
String prefTitle = entries[i].toString();
boolean selected = enabledPrefs.contains(prefId);
final int index = i;
final BottomSheetItemWithCompoundButton[] item = new BottomSheetItemWithCompoundButton[1];
item[0] = (BottomSheetItemWithCompoundButton) new BottomSheetItemWithCompoundButton.Builder()
.setChecked(selected)
.setTitle(title)
.setTitle(prefTitle)
.setLayoutId(R.layout.bottom_sheet_item_with_switch_no_icon)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean checked = !item[0].isChecked();
if (checked) {
preferenceChanged |= enabledPrefs.add(prefsIds[index]);
} else {
preferenceChanged |= enabledPrefs.remove(prefsIds[index]);
}
item[0].setChecked(checked);
tempPrefs[index] = checked;
}
})
.setTag(i)
.setTag(prefId)
.create();
items.add(item[0]);
}
@ -87,16 +113,19 @@ public class MultiSelectPreferencesBottomSheet extends MenuBottomSheetDialogFrag
super.onResume();
for (BaseBottomSheetItem item : items) {
if (item instanceof BottomSheetItemWithCompoundButton) {
Integer prefIndex = (Integer) item.getTag();
((BottomSheetItemWithCompoundButton) item).setChecked(tempPrefs[prefIndex]);
String prefId = (String) item.getTag();
((BottomSheetItemWithCompoundButton) item).setChecked(enabledPrefs.contains(prefId));
}
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBooleanArray(PREFERENCES_PARAMETERS_KEY, tempPrefs);
outState.putStringArrayList(ENABLED_PREFERENCES_IDS, new ArrayList<>(enabledPrefs));
outState.putBoolean(PREFERENCE_CHANGED, preferenceChanged);
outState.putCharSequenceArray(PREFERENCES_ENTRIES, entries);
outState.putStringArray(PREFERENCES_IDS, prefsIds);
}
@Override
@ -106,21 +135,38 @@ public class MultiSelectPreferencesBottomSheet extends MenuBottomSheetDialogFrag
@Override
protected void onRightBottomButtonClick() {
for (int i = 0; i < prefs.length; i++) {
prefs[i].set(tempPrefs[i]);
if (preferenceChanged) {
final Set<String> values = enabledPrefs;
if (multiSelectBooleanPreference.callChangeListener(values)) {
multiSelectBooleanPreference.setValues(values);
}
}
preferenceChanged = false;
dismiss();
}
public static boolean showInstance(@NonNull FragmentManager fragmentManager, String title, String description, String[] vals, OsmandSettings.OsmandPreference<Boolean>[] prefs, Fragment target) {
private MultiSelectBooleanPreference getListPreference() {
return (MultiSelectBooleanPreference) getPreference();
}
public DialogPreference getPreference() {
Bundle args = getArguments();
if (multiSelectBooleanPreference == null && args != null) {
final String key = args.getString(PREFERENCE_ID);
final DialogPreference.TargetFragment targetFragment = (DialogPreference.TargetFragment) getTargetFragment();
if (targetFragment != null) {
multiSelectBooleanPreference = (MultiSelectBooleanPreference) targetFragment.findPreference(key);
}
}
return multiSelectBooleanPreference;
}
public static boolean showInstance(@NonNull FragmentManager fragmentManager, String prefId, Fragment target) {
try {
Bundle args = new Bundle();
args.putString(PREFERENCE_ID, prefId);
MultiSelectPreferencesBottomSheet fragment = new MultiSelectPreferencesBottomSheet();
fragment.title = title;
fragment.description = description;
fragment.vals = vals;
fragment.prefs = prefs;
fragment.setTargetFragment(target, 0);
fragment.setArguments(args);
fragment.show(fragmentManager, TAG);

View file

@ -8,19 +8,23 @@ import android.support.v7.preference.PreferenceScreen;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.OsmandSettings.BooleanPreference;
import net.osmand.plus.R;
import net.osmand.plus.activities.SettingsBaseActivity;
import net.osmand.plus.activities.SettingsNavigationActivity;
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper;
import net.osmand.plus.routing.RouteProvider;
import net.osmand.plus.settings.preferences.ListPreferenceEx;
import net.osmand.plus.settings.preferences.MultiSelectBooleanPreference;
import net.osmand.plus.settings.preferences.SwitchPreferenceEx;
import net.osmand.router.GeneralRouter;
import net.osmand.util.Algorithms;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static net.osmand.plus.activities.SettingsNavigationActivity.getRouter;
@ -107,12 +111,34 @@ public class RouteParametersFragment extends BaseSettingsFragment {
}
}
if (avoidParameters.size() > 0) {
Preference avoidRouting = new Preference(ctx);
MultiSelectBooleanPreference avoidRouting = new MultiSelectBooleanPreference(ctx);
avoidRouting.setKey(AVOID_ROUTING_PARAMETER_PREFIX);
avoidRouting.setTitle(R.string.avoid_in_routing_title);
avoidRouting.setSummary(R.string.avoid_in_routing_descr);
avoidRouting.setDescription(R.string.avoid_in_routing_descr);
avoidRouting.setLayoutResource(R.layout.preference_with_descr);
avoidRouting.setIcon(getRoutingPrefIcon(AVOID_ROUTING_PARAMETER_PREFIX));
String[] entries = new String[avoidParameters.size()];
String[] prefsIds = new String[avoidParameters.size()];
Set<String> enabledPrefsIds = new HashSet<>();
for (int i = 0; i < avoidParameters.size(); i++) {
GeneralRouter.RoutingParameter p = avoidParameters.get(i);
BooleanPreference booleanRoutingPref = (BooleanPreference) settings.getCustomRoutingBooleanProperty(p.getId(), p.getDefaultBoolean());
entries[i] = SettingsBaseActivity.getRoutingStringPropertyName(ctx, p.getId(), p.getName());
prefsIds[i] = booleanRoutingPref.getId();
if (booleanRoutingPref.get()) {
enabledPrefsIds.add(booleanRoutingPref.getId());
}
}
avoidRouting.setEntries(entries);
avoidRouting.setEntryValues(prefsIds);
avoidRouting.setValues(enabledPrefsIds);
screen.addPreference(avoidRouting);
}
if (preferParameters.size() > 0) {
@ -134,7 +160,7 @@ public class RouteParametersFragment extends BaseSettingsFragment {
for (int i = 0; i < reliefFactorParameters.size(); i++) {
GeneralRouter.RoutingParameter parameter = reliefFactorParameters.get(i);
entryValues[i] = parameter.getId();
entries[i] = SettingsNavigationActivity.getRoutinParameterTitle(getContext(), parameter);
entries[i] = SettingsNavigationActivity.getRoutinParameterTitle(ctx, parameter);
if (SettingsNavigationActivity.isRoutingParameterSelected(settings, am, parameter)) {
selectedParameterId = parameter.getId();
}
@ -181,29 +207,6 @@ public class RouteParametersFragment extends BaseSettingsFragment {
}
}
@Override
public boolean onPreferenceClick(Preference preference) {
String key = preference.getKey();
if (key.equals(AVOID_ROUTING_PARAMETER_PREFIX) || key.equals(PREFER_ROUTING_PARAMETER_PREFIX)) {
List<GeneralRouter.RoutingParameter> prms = key.equals(AVOID_ROUTING_PARAMETER_PREFIX) ? avoidParameters : preferParameters;
String[] vals = new String[prms.size()];
OsmandSettings.OsmandPreference[] bls = new OsmandSettings.OsmandPreference[prms.size()];
for (int i = 0; i < prms.size(); i++) {
GeneralRouter.RoutingParameter p = prms.get(i);
vals[i] = SettingsBaseActivity.getRoutingStringPropertyName(getContext(), p.getId(), p.getName());
bls[i] = settings.getCustomRoutingBooleanProperty(p.getId(), p.getDefaultBoolean());
}
SettingsNavigationActivity.showBooleanSettings(getContext(), vals, bls, preference.getTitle());
MultiSelectPreferencesBottomSheet.showInstance(getFragmentManager(), preference.getTitle().toString(), preference.getSummary().toString(), vals, bls, this);
return false;
}
return super.onPreferenceClick(preference);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String key = preference.getKey();

View file

@ -0,0 +1,108 @@
package net.osmand.plus.settings.preferences;
import android.content.Context;
import android.support.v14.preference.MultiSelectListPreference;
import android.support.v7.preference.PreferenceDataStore;
import android.util.AttributeSet;
import net.osmand.plus.OsmandSettings.PreferencesDataStore;
import java.util.HashSet;
import java.util.Set;
public class MultiSelectBooleanPreference extends MultiSelectListPreference {
private String description;
public MultiSelectBooleanPreference(Context context) {
super(context);
}
public MultiSelectBooleanPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MultiSelectBooleanPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MultiSelectBooleanPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public CharSequence getDialogTitle() {
CharSequence dialogTitle = super.getDialogTitle();
return dialogTitle != null ? dialogTitle : getTitle();
}
@SuppressWarnings("unchecked")
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
setValues(restoreValue ? getPersistedBooleanPrefsIds(getValues()) : (Set<String>) defaultValue);
}
public void setValues(Set<String> values) {
getValues().clear();
getValues().addAll(values);
persistBooleanPrefs();
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public void setDescription(int descriptionResId) {
setDescription(getContext().getString(descriptionResId));
}
public String[] getPrefsIds() {
CharSequence[] entryValues = getEntryValues();
String[] prefsIds = new String[entryValues.length];
for (int i = 0; i < entryValues.length; i++) {
prefsIds[i] = entryValues[i].toString();
}
return prefsIds;
}
private void persistBooleanPrefs() {
if (!shouldPersist()) {
return;
}
PreferenceDataStore dataStore = getPreferenceDataStore();
if (dataStore instanceof PreferencesDataStore) {
PreferencesDataStore preferencesDataStore = (PreferencesDataStore) dataStore;
for (String prefId : getPrefsIds()) {
preferencesDataStore.putBoolean(prefId, getValues().contains(prefId));
}
}
}
public Set<String> getPersistedBooleanPrefsIds(Set<String> defaultReturnValue) {
if (!shouldPersist()) {
return defaultReturnValue;
}
Set<String> enabledPrefs = new HashSet<>();
PreferenceDataStore dataStore = getPreferenceDataStore();
if (dataStore instanceof PreferencesDataStore && getEntryValues() != null) {
PreferencesDataStore preferencesDataStore = (PreferencesDataStore) dataStore;
for (String prefId : getPrefsIds()) {
boolean enabled = preferencesDataStore.getBoolean(prefId, false);
if (enabled) {
enabledPrefs.add(prefId);
}
}
}
return enabledPrefs;
}
}