Android Tutorial PreferenceActivity tutorial

This tutorial explains how to use the new PreferenceActivity library. This library allows you to create the "standard" settings screen.

The settings screen is hosted in its own activity. As this is an external activity its declaration should be manually added to the manifest file.
I will take this opportunity to give some tips about manual modification of the manifest file which is sometimes required.

Editing AndroidManifest.xml (general overview)
As of Basic4android v1.8 it is no longer required to manually maintain the manifest file. Instead the manifest editor allows you to add extra elements as needed.
See this link for more information: http://www.b4x.com/forum/showthread.php?p=78136
For PreferenceActivity you should add the following code to the manifest editor:
B4X:
AddApplicationText(<activity android:name="anywheresoftware.b4a.objects.preferenceactivity"/>)
Back to PreferenceActivity

preference_1.png


* This image was taken on a Samsung Galaxy Tab device. On other devices the screen will look a bit different based on their default style.

PreferenceActivity library includes two main objects: PreferenceScreen and PreferenceManager.
PreferenceScreen is responsible for building the settings UI. PreferenceManager allows you to read the settings and also modify them by code.
Both these objects should usually be declared in Sub Process_Globals.
The settings are saved in a file in the internal files folder. File handling is done automatically. Note that when you reinstall an application (without uninstalling it) the files are kept so the settings will also be kept.

Each preference entry is stored as a key/value pair. The key is a string (case sensitive) and the value can be either a string or a boolean value.
Each entry must have a unique key.

Building the UI
In order to build the UI we start with a PreferenceScreen object and add entries to this object directly or to PreferenceCategory which can hold other entries.
In the above screenshot you can see a PreferenceScreen with two categories holding other entries.
Note that a PreferenceScreen can also hold secondary PreferenceScreens. In this case when the user presses on the secondary entry a new screen will appear with its entries.
There are three types of preference entries:
- Checkbox
- EditText - Opens an input dialog when the user presses on it.
- List - Open a list dialog when the user presses on it, allowing the user to select a single item.
The code that creates the above UI is:
B4X:
Sub CreatePreferenceScreen
    screen.Initialize("Settings", "")
    'create two categories
    Dim cat1, cat2 As PreferenceCategory
    cat1.Initialize("Category 1")
    cat1.AddCheckBox("check1", "Checkbox1", "This is Checkbox1", True)
    cat1.AddCheckBox("check2", "Checkbox2", "This is Checkbox2", False)
    cat1.AddEditText("edit1", "EditText1", "This is EditText1", "Hello!")
 
    cat2.Initialize("Category 2")
    cat2.AddList("list1", "List1", "This is List1", "Black", _
        Array As String("Black", "Red", "Green", "Blue"))
     
    'add the categories to the main screen
    screen.AddPreferenceCategory(cat1)
    screen.AddPreferenceCategory(cat2)
End Sub
The first string in the Add methods is the entry key followed by the title, summary and default value.
The default value is used if the key does not yet exist.

To show the preferences we use this code:
B4X:
Sub btn_Click
    StartActivity(screen.CreateIntent)
End Sub
Reading the settings
Reading the settings is done with PreferenceManager.
To retrieve the value of a specific key you should use Manager.GetString or Manager.GetBoolean with this key.
You can get a Map with all the stored keys and values by calling Manager.GetAll
If you want to only handle updated settings then you can call Manager.GetUpdatedKeys. This will return a List with the keys that were updated since the last call to this method.
Usually you will want to handle settings updated in Activity_Resume. Activity_Resume will be called right after Activity_Create when you start your program and also when the user closes the preferences screen.
Whether you want to handle all keys or just the updated keys depends on your application.

Tip:
The default values set in the PreferenceScreen.Add calls have no effect till the user actually sees the screen. It is recommended to explicitly set the default values if they do not already exist.
A simple way to do it is with code similar to:
B4X:
Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        CreatePreferenceScreen
        If manager.GetAll.Size = 0 Then SetDefaults
    End If
End Sub

Sub SetDefaults
    'defaults are only set on the first run.
    manager.SetBoolean("check1", True)
    manager.SetBoolean("check2", False)
    manager.SetString("edit1", "Hello!")
    manager.SetString("list1", "Black")
End Sub
This way our code in Activity_Resume will work correctly whether it is the first time the program runs or after the user has closed the settings page.

The program is attached.
 

Attachments

  • PreferenceActivity.zip
    6.5 KB · Views: 943
Last edited:

andrewtheart

Member
Licensed User
Longtime User
Detecting when the PreferenceActivity is closed

Hey Erel,

Is there a way to detect that the user has exited out of the Preference screen (by pressing the Back button?)

It looks like the back button keypress is being consumed by the PreferenceActivity screen.

Andrew
 

andrewtheart

Member
Licensed User
Longtime User
Nevermind - just saw that it should be handled in Activity_Resume


Hey Erel,

Is there a way to detect that the user has exited out of the Preference screen (by pressing the Back button?)

It looks like the back button keypress is being consumed by the PreferenceActivity screen.

Andrew
 

NeoTechni

Well-Known Member
Licensed User
Longtime User
I wish there was a way built in to detect when it's coming out of the preference screen, like it should call it's own event or toggle a boolean. Cause if you use more than one activity then you dont know which triggered the resume event.

What I did was set a boolean to true in the event that triggered the preference screen, so you just check that in _Resume and set it back to false.

Currently no events are available. Events can be added in the future. However you will need to handle the events from a service as your activity is paused when the preferences are displayed. This makes it a bit cumbersome.

Damn.

The only thing I could suggest then is changing it to act like an activity/service, in that it'd show up as a tab in the list of activities and we program in that. Instead of a plugin.
 
Last edited:

pinoy_ako

Member
Licensed User
Longtime User
I downloaded again the sample app from the first post. It is working great now. And something interesting i noticed in preference activty sample. When i changed the setting in the app, restarted my device, and run again the app, the setting now is the last setting before i restarted the device. Seems setting is saved automatically. I dont know where it is saved. But it is just too good feature.

Nice app.
 

latcc

Banned
demo program activity error

Noobe problem...

I am trying out the preferecesActivity library. When I try to run it on the emulator I get this error after pressing the Settings Button...

ActivityNotFoundException:
Unable to find explicit activity class {anywheresoftware.b4a.samples.preferenceactivity/anywheresoftware.b4a.objects.preferenceactivity}

I added this to the AndroidManifest.xml file:

<activity android:name="anywheresoftware.b4a.objects.preferenceactivity"/>

under the </application> tag.

What's going on here?
 

Attachments

  • prefActivity.jpg
    prefActivity.jpg
    38.8 KB · Views: 579

stevel05

Expert
Licensed User
Longtime User
Did you select Do Not Overwrite Manifest file from the Project menu?
 

latcc

Banned
Did you select Do Not Overwrite Manifest file from the Project menu?

I am simply using a modification of the demo program to understand the library so it was already selected. But comes up with this error on emulator and device. This library seems too problematic.
 

leatherguy

Member
Licensed User
Longtime User
password entry editbox

Hi Erel

I would like a password edittextbox in the preference dialog. I only can use a textbox so the password is readable, it should consist of '*' characters instead.
Is this possible?
Thanks
 

joseluis

Active Member
Licensed User
Longtime User
I would want to know how could I make PreferencesActivity Fullscreen and remove the Title bar.

I tried adding this in the Manifest editor, but it doesn't work:
B4X:
AddApplicationText(
<activity
   android:name="anywheresoftware.b4a.objects.preferenceactivity"
   android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
</activity>
)
Tried some variations of the above, without luck.
 

joseluis

Active Member
Licensed User
Longtime User
You're right! The error was elsewere (an uninitialized category), and the application crashed when the preferenceactivity was called. BTW that was the behaviour also in debug mode.

FREE TIP: If you put Theme.Light instead of Theme alone, you have a white preferences screen. :)
B4X:
android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen"
I'll investigate wether it's possible to further personalize its style with xml or not.

EDIT: hmm... I see the layout isn't inherited by the child preference screens.
 
Last edited:

RiverRaid

Active Member
Licensed User
Longtime User
Hi!

Sorry for the noob-question, but is it somehow possible to show this setings in a Panel?

Thx!
 

scardinal

New Member
Licensed User
Longtime User
app crashes when opening settings page

...after crash... opens fine...looks like something is stuck after i do an activity.finish and would need to be closed on application exit...which stays open...i think.

calling settings page just like you said....

StartActivity(screen.CreateIntent)

that call makes my app crash AFTER i have done an Activity.finish... when I restart app, and call that line....it crashes....any idea?
 
Top