EasySettings

Additional

Language
Java
Version
1.1.3 (Jul 5, 2018)
Created
Mar 29, 2018
Updated
Jul 5, 2018
Owner
Or Dvir (or-dvir)
Contributor
Or Dvir (or-dvir)
1
Activity
Badge
Generate
Download
Source code
APK file

Commercial

EasySettings

EasySettings is a library to help you add and maintain settings (AKA preferences) to your Android app. This library is designed to be as similar as possible to the "standard" way of creating and maintaining settings but much easier to implement and includes some extra features.

Gradle Dependency

In your root build.gradle, at the end of repositories, add this:

repositories {
    ...
 maven {url "https://jitpack.io" }

}

For the basic module, add this as a dependency in your app's build.gradle:

implementation 'com.github.or-dvir.EasySettings:easysettings-basic:[latest release]'

For the dialogs module, which depends on the basic module, also add this:

implementation 'com.github.or-dvir.EasySettings:easysettings-dialogs:[latest release]'

Why Use This Library?

Here are some of the drawbacks of using the Google's "standard" way (as described here):

  1. Using a specialized subclass of Activity or Fragment (PreferenceActivity and PreferenceFragment)
  2. Creating and maintaining multiple XML and Java files.
  3. Lack of basic features. For example, the inability to add a neutral button to a DialogPreference.
  4. Unnecessary complications trying to create custom settings. For example, instead of using a simple Dialog that we all know and love, we must use a specialized dialog class with new callback methods and limited functionality (see point 3).
  5. Just feels cumbersome and overly complicated to use.

On the other hand, with this library:

  1. Using a good ol` regular Activity.
  2. Requiring a minimal amount of files and file maintenance.
  3. Using standard, non-specialized Views including full functionality and all the features you are already familiar with.
  4. Creating custom settings is simple and easy.
  5. Easy to understand, use, and expand.

Things You Should be Aware of

  • The layouts of the settings are inflated at run-time (unless used on very old devices, performance should not be affected in a serious way).
  • Since this library uses regular Views and each View is wrapped in a container, the settings activity will have nested layouts (unless used on very old devices, performance should not be affected in a serious way).
  • This library uses other 3rd party libraries:
    • The basic module uses EventBus by greenrobot. Please familiarize yourself with how to use it here
    • The dialogs module uses material-dialogs by afollestad. You don't need to know how to use it, but you can learn more about it here
  • Currently there is no built-in support for Master/Detail.
  • Currently there is no built-in support for "categories" AKA "subscreens" (clicking on a setting which opens another page of settings).

Available Settings (Quick Overview)

  1. BasicSettingsObject
  2. CheckBoxSettingsObject
  3. SwitchSettingsObject
  4. HeaderSettingsObject
  5. SeekBarSettingsObject
  6. EditTextSettingsDialog - available in dialogs module
  7. ListSettingsDialog (can be single-choice or multi-choice) - available in dialogs module

See further details for each object below.

How to Use This Library

1. Creating your settings

The first thing you need to do is create your settings. You can use the method EasySettings.createSettingsArray(SettingsObject...) like this:

ArrayList<SettingsObject> mySettings List = EasySettings.createSettingsArray(
    new BasicSettingsObject.Builder("basicSettingsKey1", "fancy title 1")
      .setSummary("fancy summary")
      .build(),
    new BasicSettingsObject.Builder("basicSettingsKey2","fancy title 2")
      .setSummary("not so fancy summary")
      .build(),
    new CheckBoxSettingsObject.Builder("cehckBoxKey", "checkbox title", false)
      .setSummary("checkbox summary")
      .build());

Or you can also create it in any other way. For example:

BasicSettingsObject setting1 =
  new BasicSettingsObject.Builder("fancy title 1")
    .setSummary("fancy summary")
    .build();
CheckBoxSettingsObject setting2 =
  new CheckBoxSettingsObject.Builder("checkboxkey", "checkbox title", false)
    .setSummary("checkbox summary")
    .build();
SwitchSettingsObject setting3 =
  new SwitchSettingsObject.Builder("switchkey", "switch title", true)
    .setSummary("switch summary")
    .build();
mySettingsList = new ArrayList<>();
mySettingsList.add(setting1);
mySettingsList.add(setting2);
mySettingsList.add(setting3);

Note: This does not actually create the settings but simply creates an array of settings to be created and initialized in step 2.

2. Initializing your settings

Immediately after creating your settings, you must initialize them by calling the method EasySettings.initializeSettings(context, mySettingsList);

This method does the following:

  1. Initializes all of the settings objects with their default values.
  2. Actually creates (and saves) the settings in the apps' SharedPreferences (unless the setting already exists).
  3. Checks the validity of previously saved values and, if needed, corrects them. For instance, you have a SeekBarSettingsObject with the range of 1-10 and the user sets it to 10. In your next version for some reason you change the range to be 1-5, so now the previously saved value (10) is no longer valid. By default, this method will change the saved value to the default one so it is now valid within the newly created range.

Note: Steps 1 and 2 should be done ASAP in the OnCreate() method of your apps' main activity. The reason is that we want access to our settings as soon as possible and we want the values to be valid (see SeekBarSettingsObject example above).

A full example should look like this:

@Override
protected void onCreate(Bundle savedInstanceState)
{
 //this is the main activity
    
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
    
    ArrayList<SettingsObject> mySettings List = EasySettings.createSettingsArray(
   new BasicSettingsObject.Builder("basicSettingsKey1", "fancy title 1")
     .setSummary("fancy summary")
     .build(),
   new BasicSettingsObject.Builder("basicSettingsKey2","fancy title 2")
     .setSummary("not so fancy summary")
     .build(),
   new CheckBoxSettingsObject.Builder("cehckBoxKey", "checkbox title", false)
     .setSummary("checkbox summary")
     .build());

 EasySettings.initializeSettings(this, mySettingsList);
  
 //rest of your code
}

3. Creating the settings activity

We're going to need that ArrayList<SettingsObject> we created earlier in the settings activity and maybe you'd also want to have it available in other places in your app. It is up to you to decide how to make that list available to other components of your app. Here are some options:

  • Creating a singleton.
  • Create a static list in a base activity which all other activities inherit.
  • Simply transfer it via an Intent (requires some maintenance - see the sample for an example).

3.1 The layout

The layout simply needs a container onto which the settings will be inflated. Most likely this will be a vertical LinearLayout. It is recommended to wrap this container with a ScrollView so all your settings will fit on smaller screens (unnecessary if you only have a few settings).

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/settingsContainer"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

    </LinearLayout>

</ScrollView>

3.2 The activity

In the onCreate() method of your settings activity, you will need to call the method

EasySettings.inflateSettingsLayout(Context, ViewGroup, ArrayList<SettingsObject>);

where ViewGroup is the settings container onto which the settings will be inflated. A full example should look like this:

@Override
protected void onCreate(Bundle savedInstanceState)
{
 //this is the settings activity
 
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_settings);
 LinearLayout container = findViewById(R.id.settingsContainer);
 settingsList = (ArrayList<SettingsObject>) getIntent().getSerializableExtra(ActivityMain.EXTRA_SETTINGS_LIST);

 EasySettings.inflateSettingsLayout(this, container, settingsList);
}

4. Accessing the settings

Note: The built-in objects automatically save the value to SharedPreferences when changed and usually there is no need to manually save them (see exceptions below and in the sample app).

Retrieving a setting can be done like so:

boolean value = EasySettings.retrieveSettingsSharedPrefs(this).getBoolean("checkBoxKey", false);

We can also manually edit a value:

EasySettings.retrieveSettingsSharedPrefs(this)
  .edit()
  .putBoolean("checkBoxKey", false)
  .apply();

Warning: We must be careful when manually editing a value like this because our ArrayList<SettingsObject> must also be updated in order to prevent bugs.

Another way of accessing settings can be done like this:

SettingsObject mySettObj = EasySettings.findSettingsObject(String, ArrayList<SettingsObject>);

If manually editing mySettObj, please note that the method setValue(value) simply changes the value of the object and does NOT save it in SharedPreferences. In order to change the value of the object AND save it to SharedPreferences, use setValueAndSaveSetting(context, value).

Warning: The method setValueAndSaveSetting(context, value) does not perform validity checks on the given value! For example, if this method is used on a SeekBarSettingsObject, it is assumed that the given value is within the range of the SeekBarSettingsObject.

Note: In most cases there is no need to manually edit the values! In order to prevent bugs, you should avoid manually editing values as much as possible.

Available Settings (In Detail)

Note: It is possible that there are some features which were overlooked the readme file. Please see the java docs and source code for full details.

All objects in this library extend SettingsObject and all of them have the following optional features via their builders (they are self-explanatory - see java docs for full details):

  • setIcon(@Nullable @DrawableRes Integer iconId). Not using this method at all will align the setting to the start of the container. Passing null means there is no icon, but the setting will be aligned as if it has one. This is useful if we have some settings which have icons and some that don't and they should be visually aligned. If used, this will override setIconDrawable(@Nullable Drawable iconDrawable)
  • setIconDrawable(@Nullable Drawable iconDrawable). same as setIcon(@Nullable @DrawableRes Integer iconId), except it takes a Drawable. NOTE: this Drawable is overridden by setIcon(@Nullable @DrawableRes Integer iconId)
  • setSummary(String summary)
  • setUseValueAsSummary() If used, this will override setSummary(String summary)
  • addDivider()

BasicSettingsObject

A settings object which simply sends an event when clicked.

Type of value saved: none (Void).

Optional features: none.

Event: BasicSettingsClickEvent

If we want a BasicSettingsObject to save a value, this must be done manually (see "Notification Sound" setting in the sample app).