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.basic4ppc.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: 438
Last edited:

David S

Member
Licensed User
Google could do better with the documentation.

First you select what type of input, in this case
TYPE_CLASS_NUMBER (value = 2)

then add flags to vary the behavious eg
TYPE_NUMBER_FLAG_DECIMAL (value = 8192)

So the final integer value = Bit.OR(TYPE_CLASS_NUMBER ,TYPE_NUMBER_FLAG_DECIMAL ) = 8194

BlueJay


Actually Google's documentation sucks big time....

Dim x As Int = ett.INPUT_TYPE_NUMBERS
Dim y As Int = ett.INPUT_TYPE_DECIMAL_NUMBERS

x = 2
y = 12,029​

So now that I know the Google Android documentation is so untrustworthy, as apparently Erel is also aware of, if you need the value of the input type (as in AddEditText2 - post # 155) then you have to pull it from the view.

Seems a shame you have to add the overhead of creating a edittext view just to get a parameter because Google may change it's value in the future.

But hey, if they are calling these objects "Views" instead of "Controls" then you have to be on your toes. lol
 

ivanthomson

Member
Licensed User
Thanks for the tutorial Erel.

Is there any example of adding a secondary preference screen to the first screen and then adding items to the secondary and actually opening it when the user clicks on the item in the first screen that leads to the second?

For example;

If I have a preference screen built up and I enter this line of code;

cat3.AddPreferenceScreen(PFsecondaryscreen)

How do I add items to PFsecondaryscreen and how do I open it?

Your tutorial mentions being able to do this, but unfortunately, it doesn't show how. I've tried things but I can't seem to figure it out.

Thanks.
 

Erel

Administrator
Staff member
Licensed User
Use this sub (based on the tutorial code):
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", "")
   
   cat2.Initialize("Category 2")
   cat2.AddList("list1", "List1", "This is List1", "", _
  Array As String("Black", "Red", "Green", "Blue"))
     
   'add the categories to the main screen
   screen.AddPreferenceCategory(cat1)
   screen.AddPreferenceCategory(cat2)
   Dim screen2 As PreferenceScreen
   screen2.Initialize("screen2", "screen2 summary")
   Dim s2cat1 As PreferenceCategory
   s2cat1.Initialize("Category on 2nd screen")
   s2cat1.AddEditText("edit2", "EditText2", "This is EditText2", "")
   screen2.AddPreferenceCategory(s2cat1)
   screen.AddPreferenceScreen(screen2)
End Sub
 

ivanthomson

Member
Licensed User
Use this sub (based on the tutorial code):
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", "")
  
   cat2.Initialize("Category 2")
   cat2.AddList("list1", "List1", "This is List1", "", _
  Array As String("Black", "Red", "Green", "Blue"))
    
   'add the categories to the main screen
   screen.AddPreferenceCategory(cat1)
   screen.AddPreferenceCategory(cat2)
   Dim screen2 As PreferenceScreen
   screen2.Initialize("screen2", "screen2 summary")
   Dim s2cat1 As PreferenceCategory
   s2cat1.Initialize("Category on 2nd screen")
   s2cat1.AddEditText("edit2", "EditText2", "This is EditText2", "")
   screen2.AddPreferenceCategory(s2cat1)
   screen.AddPreferenceScreen(screen2)
End Sub


Thanks, again, Erel. I much appreciate the help and the tutorials. You do a fantastic job!
 

lemonisdead

Well-Known Member
Licensed User
I will open new activity by click on item.
You want to open a new activity from the PreferenceActivity ? If yes, you should take a look at AHPreferenceActivity which extends this one
 

khosrwb

Active Member
Licensed User
You want to open a new activity from the PreferenceActivity ? If yes, you should take a look at AHPreferenceActivity which extends this one
yes I will too .
if possible write code for me.
I read AhpreferenceActivity library , but I don't know .
B4X:
StartActivity(main2)

thanks
 

lemonisdead

Well-Known Member
Licensed User
if possible write code for me.
Hello,
Please find a modified example attached.
The call to the Activity named "main2" is done via an intent and registred in the Manifest. So don't forget to replace the package's name by your own in your own app.
 

Attachments

  • main2.zip
    8.1 KB · Views: 281

khosrwb

Active Member
Licensed User
Hello,
Please find a modified example attached.
The call to the Activity named "main2" is done via an intent and registred in the Manifest. So don't forget to replace the package's name by your own in your own app.

thanks lemonisdead
your help was usefull for me.
 

palmzac

Active Member
Licensed User
Hi Erel,

OIC. Thank for your help ! :)


You can change the activity theme.
B4X:
AddApplicationText(
<activity
  android:name="anywheresoftware.b4a.objects.preferenceactivity"
  android:theme="@android:style/Theme.Holo.Light">
</activity>
)
 

jairbj

Member
Licensed User
Hi friends, does it is possible to add an ActionBar to the top of preference screen with a "back" button?
 
Top