B4A Library Preferences - Material Design Preferences

corwin42

Expert
Licensed User
This library provides a framework to create nice looking Material Design Preferences down to API9. It uses this GitHub project to fix some bugs in the android support preferences stuff. It also adds some nice features like simple icon tinting, simple menu list preferences and a color picker.

For a guide on how to implement settings for Material Design read this.

Installation:
  • Extract all of the PreferencesLibX_XX.zip file to your additional libraries folder. These are .xml, .jar, 4 .aar files.
  • Requires AppCompat library.
  • Requires B4A 6.31+
minimum SDK Version: 14
Needs support library 27

If you are updating you can delete the old library aar files.

Your Support:
Creating libraries and wrappers for existing library projects is a lot of work. The use of this library is totally free and you even don't need to mention in your app that you use it.
But if you use this library in your projects and you think it is useful to you please consider to make a donation:

Thanks very much for your support.

Usage:


You need to use AppCompat Library together with this library.
Don't forget to add the Preference library to your project.

1. Enhance your theme in manifest editor
Add a preferenceTheme item and the two items for the IconTint:
B4X:
CreateResource(values, theme.xml,
<resources>
    <style name="MyAppTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">#0098FF</item>
        <item name="colorPrimaryDark">#007CF5</item>
        <item name="colorAccent">#FF5522</item>
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
        <item name="preferenceTheme">@style/PreferenceThemeOverlay.Material</item>
        <item name="asp_preferenceIconTint">?colorAccent</item>
        <item name="asp_preferenceDialogIconTint">?asp_preferenceIconTint</item>
        <item name="windowActionModeOverlay">true</item>
    </style>
</resources>
)
2. Extend from AppCompatPreferenceActivity
B4X:
#Extends: de.amberhome.preferences.AppCompatPreferenceActivity
3. Add PreferenceView to your Layout (with designer or by code)
DesignerPreferenceView.png

4. Load the Layout in Activity_Create() as normal

5. Create your Preference elements in PreferenceView_Ready() event.

See the example for detailed usage.

The example has minSdkVersion set to 14. This is because the MaterialDateTimePicker needs this. The Preference library itself will work with a minimal SDK version of 9.

The example projects additionally needs MaterialDateTimePicker, XMLLayoutBuilder and DateUtils libraries.

Reference:
Preferences
Author:
Markus Stipp
Version: 1.11
  • CheckBoxPreference
    Events:
    • PreferenceChanged (Preference As Preference, NewValue As Object)
    • PreferenceClicked (Preference As Preference)
    Methods:
    • Initialize (PreferenceView As PreferenceViewWrapper, EventName As String, Key As String, DefaultValue As Object)
      Initializes the object
    • IsInitialized As Boolean
    Properties:
    • Checked As Boolean
    • DefaultValue As Object [write only]
    • Dependency As String
    • DisableDependentsState As Boolean
    • Enabled As Boolean
    • Icon As Drawable
    • IconPaddingEnabled As Boolean [write only]
    • IconTintEnabled As Boolean [write only]
    • Intent As Intent
    • Key As String
    • Order As Int
    • Persistent As Boolean
    • Selectable As Boolean
    • Summary As String
    • SummaryOffText As CharSequence
    • SummaryOnText As CharSequence
    • SummaryTextColor As Int [write only]
    • Title As String
    • TitleTextColor As Int [write only]
    • Visible As Boolean
  • ColorPreference
    Events:
    • PreferenceChanged (Preference As Preference, NewValue As Object)
    • PreferenceClicked (Preference As Preference)
    Methods:
    • GetNameForColor (Color As Int) As CharSequence
    • Initialize (PreferenceView As PreferenceViewWrapper, EventName As String, Key As String, DefaultValue As Object)
      Initializes the object
    • IsInitialized As Boolean
    Properties:
    • Color As Int
    • ColorNames()() As CharSequence
    • ColorValues()() As Int
    • ColumnCount As Int
    • DefaultValue As Object [write only]
    • Dependency As String
    • DialogIcon As Drawable
    • DialogIconTintEnabled As Boolean [write only]
    • DialogTitle As CharSequence
    • Enabled As Boolean
    • Icon As Drawable
    • IconPaddingEnabled As Boolean [write only]
    • IconTintEnabled As Boolean [write only]
    • Intent As Intent
    • Key As String
    • NegativeButtonText As CharSequence
    • Order As Int
    • Persistent As Boolean
    • PositiveButtonText As CharSequence
    • Selectable As Boolean
    • Summary As String
    • SummaryTextColor As Int [write only]
    • SwatchSize As Int
    • Title As String
    • TitleTextColor As Int [write only]
    • Visible As Boolean
  • EditTextPreference
    Events:
    • EditTextCreated (Edit As EditText)
    • PreferenceChanged (Preference As Preference, NewValue As Object)
    • PreferenceClicked (Preference As Preference)
    Methods:
    • Initialize (PreferenceView As PreferenceViewWrapper, EventName As String, Key As String, DefaultValue As Object)
      Initializes the object
    • IsInitialized As Boolean
    Properties:
    • DefaultValue As Object [write only]
    • Dependency As String
    • DialogIcon As Drawable
    • DialogIconTintEnabled As Boolean [write only]
    • DialogMessage As CharSequence
    • DialogTitle As CharSequence
    • Enabled As Boolean
    • Icon As Drawable
    • IconPaddingEnabled As Boolean [write only]
    • IconTintEnabled As Boolean [write only]
    • Intent As Intent
    • Key As String
    • NegativeButtonText As CharSequence
    • Order As Int
    • Persistent As Boolean
    • PositiveButtonText As CharSequence
    • Selectable As Boolean
    • Summary As String
    • SummaryTextColor As Int [write only]
    • Text As String
    • Title As String
    • TitleTextColor As Int [write only]
    • Visible As Boolean
  • ListPreference
    Events:
    • PreferenceChanged (Preference As Preference, NewValue As Object)
    • PreferenceClicked (Preference As Preference)
    Fields:
    • MENU_MODE_DIALOG As Int
    • MENU_MODE_SIMPLE_ADAPTIVE As Int
    • MENU_MODE_SIMPLE_DIALOG As Int
    • MENU_MODE_SIMPLE_MENU As Int
    Methods:
    • Initialize (PreferenceView As PreferenceViewWrapper, EventName As String, Key As String, DefaultValue As Object)
      Initializes the object
    • IsInitialized As Boolean
    Properties:
    • DefaultValue As Object [write only]
    • Dependency As String
    • DialogIcon As Drawable
    • DialogIconTintEnabled As Boolean [write only]
    • DialogTitle As CharSequence
    • Enabled As Boolean
    • Entries As Map
    • Icon As Drawable
    • IconPaddingEnabled As Boolean [write only]
    • IconTintEnabled As Boolean [write only]
    • Intent As Intent
    • Key As String
    • MenuMode As Int
    • NegativeButtonText As CharSequence
    • Order As Int
    • Persistent As Boolean
    • PositiveButtonText As CharSequence
    • Selectable As Boolean
    • SimpleMenuPreferredWidthUnit As Float
    • Summary As String
    • SummaryTextColor As Int [write only]
    • Title As String
    • TitleTextColor As Int [write only]
    • Value As String
    • Visible As Boolean
  • MultiSelectListPreference
    Events:
    • PreferenceChanged (Preference As Preference, NewValue As List)
    • PreferenceClicked (Preference As Preference)
    Methods:
    • Initialize (PreferenceView As PreferenceViewWrapper, EventName As String, Key As String, DefaultValue As List)
      Initializes the object
    • IsInitialized As Boolean
    Properties:
    • DefaultValue As Object [write only]
    • Dependency As String
    • DialogIcon As Drawable
    • DialogIconTintEnabled As Boolean [write only]
    • DialogTitle As CharSequence
    • Enabled As Boolean
    • Entries As Map
    • Icon As Drawable
    • Intent As Intent
    • Key As String
    • NegativeButtonText As CharSequence
    • Order As Int
    • Persistent As Boolean
    • PositiveButtonText As CharSequence
    • Selectable As Boolean
    • SelectedItems() As Boolean [read only]
    • Summary As String
    • Title As String
    • Values As List
    • Visible As Boolean
  • Preference
    Events:
    • PreferenceChanged (Preference As Preference, NewValue As Object)
    • PreferenceClicked (Preference As Preference)
    Methods:
    • Initialize (PreferenceView As PreferenceViewWrapper, EventName As String, Key As String, DefaultValue As Object)
      Initializes the object
    • IsInitialized As Boolean
    Properties:
    • DefaultValue As Object [write only]
    • Dependency As String
    • Enabled As Boolean
    • Icon As Drawable
    • Intent As Intent
    • Key As String
    • Order As Int
    • Persistent As Boolean
    • Selectable As Boolean
    • Summary As String
    • Title As String
    • Visible As Boolean
  • PreferenceCategory
    Events:
    • PreferenceChanged (Preference As Preference, NewValue As Object)
    • PreferenceClicked (Preference As Preference)
    Methods:
    • AddCategory (EventName As String, Key As String, Title As String) As PreferenceCategoryWrapper
    • AddCheckBoxPreference (EventName As String, Key As String, Title As String, SummaryOn As String, SummaryOff As String, Default As Boolean) As CheckBoxPreferenceWrapper
    • AddColorPreference (EventName As String, Key As String, Title As String, Summary As String, Default As Int, Colors() As Int, Names() As String) As ColorPreferenceWrapper
    • AddEditTextPreference (EventName As String, Key As String, Title As String, Summary As String, Default As String) As EditTextPreferenceWrapper
    • AddListPreference (EventName As String, Key As String, Title As String, Summary As String, Default As String, Values() As String, Texts() As String) As ListPreferenceWrapper
    • AddMultiSelectListPreference (EventName As String, Key As String, Title As String, Summary As String, Default As List, Values() As String, Texts() As String) As MultiSelectListPreferenceWrapper
    • AddPreference (Pref As Preference) As Boolean
    • AddSeekBarDialogPreference (EventName As String, Key As String, Title As String, Summary As String, Default As Int, Min As Int, Max As Int) As SeekBarDialogPreferenceWrapper
    • AddSeekBarPreference (EventName As String, Key As String, Title As String, Summary As String, Default As Int, Min As Int, Max As Int) As SeekBarPreferenceWrapper
    • AddSimplePreference (EventName As String, Key As String, Title As String, Summary As String, Default As String) As SimplePreferenceWrapper
    • AddSwitchPreference (EventName As String, Key As String, Title As String, SummaryOn As String, SummaryOff As String, Default As Boolean) As SwitchPreferenceWrapper
    • FindPreference (Key As String) As Preference
    • GetPreference (Index As Int) As Preference
    • Initialize (PreferenceView As PreferenceViewWrapper, EventName As String, Key As String, DefaultValue As Object)
      Initializes the object
    • IsInitialized As Boolean
    • RemoveAll
    • RemovePreference (Pref As Preference)
    Properties:
    • DefaultValue As Object [write only]
    • Dependency As String
    • Enabled As Boolean
    • Icon As Drawable
    • IconPaddingEnabled As Boolean [write only]
    • IconTintEnabled As Boolean [write only]
    • Intent As Intent
    • Key As String
    • Order As Int
    • Persistent As Boolean
    • PreferenceCount As Int [read only]
    • Selectable As Boolean
    • Summary As String
    • SummaryTextColor As Int [write only]
    • Title As String
    • TitleTextColor As Int [write only]
    • Visible As Boolean
  • PreferenceManager
    Methods:
    • ClearAll
      Clears all stored entries.
    • GetAll As Map
      Returns a Map with all the Keys and Values. Note that changes to this map will not affect the stored values.
    • GetBoolean (Key As String) As Boolean
      Returns the Boolean value mapped to the given key. Returns False if the key is not found.
    • GetBoolean2 (Key As String, Default As Boolean) As Boolean
      Returns the Boolean value mapped to the given key. Returns the default value if the key is not found.
    • GetInt (Key As String) As Int
    • GetInt2 (Key As String, Default As Int) As Int
    • GetList (Key As String) As List
    • GetList2 (Key As String, Default As List) As List
    • GetLong (Key As String) As Long
      Returns the Long value mapped to the given key. Returns -1 if the key is not found.
    • GetLong2 (Key As String, Default As Long) As Long
      Returns the Long value mapped to the given key. Returns the default value if the key is not found.
    • GetString (Key As String) As String
      Returns the String value mapped to the given key. Returns an empty string if the key is not found.
    • GetString2 (Key As String, Default As String) As String
      Return the String value mapped to the given key. Returns the default value if the key is not found.
    • GetUpdatedKeys As List
      Returns a list with the keys that were updated since the last call to GetUpdatedKeys.
      Note that the updated keys may include keys with unchanged values.
    • SetBoolean (Key As String, Value As Boolean)
      Maps the given key to the given Boolean value.
    • SetInt (Key As String, Value As Int)
    • SetList (Key As String, Values As List)
      Maps the given key to the given List.
    • SetLong (Key As String, Value As Long)
      Maps the given key to the given Long value.
    • SetString (Key As String, Value As String)
      Maps the given key to the given String value.
  • PreferenceView
    Events:
    • Ready (Preference As PreferenceView)
    Methods:
    • AddCategory (EventName As String, Key As String, Title As String) As PreferenceCategoryWrapper
    • AddCheckBoxPreference (EventName As String, Key As String, Title As String, SummaryOn As String, SummaryOff As String, Default As Boolean) As CheckBoxPreferenceWrapper
    • AddColorPreference (EventName As String, Key As String, Title As String, Summary As String, Default As Int, Colors() As Int, Names() As String) As ColorPreferenceWrapper
    • AddEditTextPreference (EventName As String, Key As String, Title As String, Summary As String, Default As String) As EditTextPreferenceWrapper
    • AddListPreference (EventName As String, Key As String, Title As String, Summary As String, Default As String, Values() As String, Texts() As String) As ListPreferenceWrapper
    • AddMultiSelectListPreference (EventName As String, Key As String, Title As String, Summary As String, Default As List, Values() As String, Texts() As String) As MultiSelectListPreferenceWrapper
    • AddPreference (Pref As Preference)
    • AddSeekBarDialogPreference (EventName As String, Key As String, Title As String, Summary As String, Default As Int, Min As Int, Max As Int) As SeekBarDialogPreferenceWrapper
    • AddSeekBarPreference (EventName As String, Key As String, Title As String, Summary As String, Default As Int, Min As Int, Max As Int) As SeekBarPreferenceWrapper
    • AddSimplePreference (EventName As String, Key As String, Title As String, Summary As String, Default As String) As SimplePreferenceWrapper
    • AddSwitchPreference (EventName As String, Key As String, Title As String, SummaryOn As String, SummaryOff As String, Default As Boolean) As SwitchPreferenceWrapper
    • DesignerCreateView (base As PanelWrapper, lw As LabelWrapper, props As Map)
    • Initialize (EventName As String, Parent As ViewGroup)
  • SeekBarDialogPreference
  • Events:
    • PreferenceChanged (Preference As Preference, NewValue As Object)
    • PreferenceClicked (Preference As Preference)
    Methods:
    • Initialize (PreferenceView As PreferenceViewWrapper, EventName As String, Key As String, DefaultValue As Object)
      Initializes the object
    • IsInitialized As Boolean
    Properties:
    • DefaultValue As Object [write only]
    • Dependency As String
    • DialogIcon As Drawable
    • DialogIconTintEnabled As Boolean [write only]
    • DialogMessage As CharSequence
    • DialogTitle As CharSequence
    • Enabled As Boolean
    • Icon As Drawable
    • IconPaddingEnabled As Boolean [write only]
    • IconTintEnabled As Boolean [write only]
    • Intent As Intent
    • Key As String
    • Max As Int
    • Min As Int
    • NegativeButtonText As CharSequence
    • Order As Int
    • Persistent As Boolean
    • PositiveButtonText As CharSequence
    • Progress As Int
    • Selectable As Boolean
    • Summary As String
    • SummaryTextColor As Int [write only]
    • Title As String
    • TitleTextColor As Int [write only]
    • Visible As Boolean
  • SeekBarPreference
    Events:
    • PreferenceChanged (Preference As Preference, NewValue As Object)
    • PreferenceClicked (Preference As Preference)
    • ProgressChanged (Progress As Int, UserChanged As Boolean)
    Methods:
    • Initialize (PreferenceView As PreferenceViewWrapper, EventName As String, Key As String, DefaultValue As Object)
      Initializes the object
    • IsInitialized As Boolean
    Properties:
    • Adjustable As Boolean
    • DefaultValue As Object [write only]
    • Dependency As String
    • Enabled As Boolean
    • Icon As Drawable
    • IconPaddingEnabled As Boolean [write only]
    • IconTintEnabled As Boolean [write only]
    • Info As CharSequence
    • Intent As Intent
    • Key As String
    • Max As Int
    • Min As Int
    • Order As Int
    • Persistent As Boolean
    • SeekBarIncrement As Int
    • Selectable As Boolean
    • ShowValue As Boolean
    • Summary As String
    • SummaryTextColor As Int [write only]
    • Title As String
    • TitleTextColor As Int [write only]
    • Value As Int
    • Visible As Boolean
  • SimplePreference
    Events:
    • PreferenceChanged (Preference As Preference, NewValue As Object)
    • PreferenceClicked (Preference As Preference)
    • PreferenceLongClicked (Preference As Preference))
    Methods:
    • Initialize (PreferenceView As PreferenceViewWrapper, EventName As String, Key As String, DefaultValue As Object)
      Initializes the object
    • IsInitialized As Boolean
    Properties:
    • DefaultValue As Object [write only]
    • Dependency As String
    • Enabled As Boolean
    • Icon As Drawable
    • IconPaddingEnabled As Boolean [write only]
    • IconTintEnabled As Boolean [write only]
    • Intent As Intent
    • Key As String
    • Order As Int
    • Persistent As Boolean
    • Selectable As Boolean
    • Summary As String
    • SummaryTextColor As Int [write only]
    • Title As String
    • TitleTextColor As Int [write only]
    • Visible As Boolean
  • SwitchPreference
    Events:
    • PreferenceChanged (Preference As Preference, NewValue As Object)
    • PreferenceClicked (Preference As Preference)
    Methods:
    • Initialize (PreferenceView As PreferenceViewWrapper, EventName As String, Key As String, DefaultValue As Object)
      Initializes the object
    • IsInitialized As Boolean
    Properties:
    • Checked As Boolean
    • DefaultValue As Object [write only]
    • Dependency As String
    • DisableDependentsState As Boolean
    • Enabled As Boolean
    • Icon As Drawable
    • IconPaddingEnabled As Boolean [write only]
    • IconTintEnabled As Boolean [write only]
    • Intent As Intent
    • Key As String
    • Order As Int
    • Persistent As Boolean
    • Selectable As Boolean
    • Summary As String
    • SummaryOffText As CharSequence
    • SummaryOnText As CharSequence
    • SummaryTextColor As Int [write only]
    • Title As String
    • TitleTextColor As Int [write only]
    • Visible As Boolean
History:
V1.00:
  • Initial version
V1.01:
  • Fix: Change packagename to anywheresoftware.b4a.orbjects to reduce resource fields
V1.10:
  • New: MultiSelectListPreference
V1.11
  • Fix: Removed DialogMessage property from dialogs with lists (not supported)
  • Fix: Added missing properties to MultiSelectPreference
V1.12
  • Fix: PreferenceCategory.AddMultiSelectListPreference() should work now
  • Fix: AddPreference() should work with all preferences
  • New: Added RemoveKey() to PreferenceManager
  • Fix: Remove internal resource files
V1.14
  • Fix: Fix crash on screen rotation
  • Fix: Updated to support-preferences library 1.2.7 (fixes crash with ringtone manager on Samsung devices, fixes memory leak)
  • New: Better support for CharSequences
V2.00
  • Fix: Updated to support-preferences library 2.2.0 (fixes crashes with support libraries 27)
V3.00
  • Fix: Should work with androidx support libraries.
  • Fix: Updated to support-prefernces library 3.0.0dev
  • Attention: Removed RingtonePreference since it is not supported by androidx support library anymore!
ToDo:
  • Currently there is nearly no popup help.
 

Attachments

Last edited:

johndb

Active Member
Licensed User
Thank you very much for this excellent library @corwin42. The example works very well. I am in the process of replacing the preferences in one of my applications and I received the dreaded "Too many method references" error. It would appear that your library contains and is adding over 23,000 references making it unusable for larger applications. Are your duplicating appcompat classes and components?
 

DonManfred

Expert
Licensed User
@johndb your issue is the first i see in the forum since release of the new maven repos.
do you include old jars like android-support-v4.jar in your app?

Usually it was the old android-support-v4 which raises this amount of method references...
 

johndb

Active Member
Licensed User
@johndb your issue is the first i see in the forum since release of the new maven repos.
do you include old jars like android-support-v4.jar in your app?

Usually it was the old android-support-v4 which raises this amount of method references...
Thank you for your advice @DonManfred. No, the android-support-v4.jar is not included in the application.
 

corwin42

Expert
Licensed User
It was more a problem of the google play services.

I don't believe it is the preferences library. It just references preferences-v7, appcompat-v7 and the aars provided with the library.

What other libraries do you add to your project?
Can you post the full error stack?
 

DonManfred

Expert
Licensed User
is not included in the application
maybe not knowingly?

Worth a check if an full size android-support-v4.jar is inside your additional libs folder or just a dummy-file (22 bytes) (or even no android-support-v4.jar file at all)

On the other hand you can try to reproduce the issue in a small new project.
 
Last edited:

johndb

Active Member
Licensed User
maybe not knowingly?

Worth a check if an full size android-support-v4.jar is inside your additional libs folder or just a dummy-file (22 bytes) (or even no android-support-v4.jar file at all)

On the other hand you can try to reproduce the issue in a small new project.
I removed the android-support-v4.jar from my additional libraries folder and the "exceeded number of references" issue still exists.
My project is quite large so it not practical to prune down the project smaller although I will most likely have to in order to determine the cause of this error.
The application references 55 libraries, several of which are my own. There are several 100's of thousands of lines of code so pruning would be quite time consuming.
@corwin42's example by itself works flawlessly. I'll keep you informed as to what I find out.

The material based preference handling is the last module for my application. This is why @corwin42's library is of great interest to me.

Thank you @DonManfred and @corwin42 for your help.

John
 
Last edited:

johndb

Active Member
Licensed User
It was more a problem of the google play services.

I don't believe it is the preferences library. It just references preferences-v7, appcompat-v7 and the aars provided with the library.

What other libraries do you add to your project?
Can you post the full error stack?
It appears that android-support-v4 is being referenced by one of the used libraries. I'll have to troubleshoot to determine which one. Here is the error stack:

B4A version: 6.50
Parsing code. (0.32s)
Compiling code. (0.55s)
Compiling layouts code. (0.05s)
Organizing libraries. (8.68s)
Generating R file. (2.49s)
Compiling debugger engine code. (4.01s)
Compiling generated Java code. (5.80s)
Convert byte code - optimized dex. Error
trouble writing output: Too many field references: 87083; max is 65536.
You may try using --multi-dex option.
References by package:
3 ADR.stringdemo
10 MLHelper
8 a.a.a.a
35 a.a.a.b
8 a.a.a.b.a
11 a.a.a.b.b
1 a.a.a.c
41 a.a.a.d
95 a.a.a.e
13 a.a.a.f
18 a.a.a.g
10 a.a.a.h
5 a.a.a.i
3 android.accounts
30 android.app
1 android.content
39 android.content.pm
9 android.content.res
3 android.database
95 android.graphics
1 android.graphics.drawable
3 android.hardware
1 android.location
2 android.media
1 android.media.browse
4 android.net
35 android.os
3 android.print
8 android.provider
5 android.support.annotation
6 android.support.compat
6 android.support.coreui
6 android.support.coreutils
1 android.support.customtabs
3240 android.support.design
58 android.support.design.internal
676 android.support.design.widget
6 android.support.fragment
159 android.support.graphics.drawable
6 android.support.graphics.drawable.animated
6 android.support.mediacompat
6 android.support.v4
13 android.support.v4.accessibilityservice
17 android.support.v4.animation
863 android.support.v4.app
111 android.support.v4.content
1 android.support.v4.content.pm
1 android.support.v4.content.res
9 android.support.v4.graphics
41 android.support.v4.graphics.drawable
4 android.support.v4.hardware.display
12 android.support.v4.hardware.fingerprint
10 android.support.v4.internal.view
348 android.support.v4.media
300 android.support.v4.media.session
7 android.support.v4.net
19 android.support.v4.os
63 android.support.v4.print
9 android.support.v4.provider
55 android.support.v4.text
6 android.support.v4.text.util
102 android.support.v4.util
433 android.support.v4.view
137 android.support.v4.view.accessibility
8 android.support.v4.view.animation
495 android.support.v4.widget
391 android.support.v7.app
3240 android.support.v7.appcompat
8 android.support.v7.content.res
18 android.support.v7.graphics.drawable
2 android.support.v7.internal.widget
3458 android.support.v7.preference
3240 android.support.v7.recyclerview
1 android.support.v7.text
2 android.support.v7.transition
124 android.support.v7.util
77 android.support.v7.view
248 android.support.v7.view.menu
1444 android.support.v7.widget
89 android.support.v7.widget.helper
1 android.support.v7.widget.util
6 android.text
1 android.text.util
15 android.util
24 android.view
10 android.view.accessibility
1 android.view.inputmethod
5 android.webkit
14 android.widget
144 anywheresoftware.b4a
17 anywheresoftware.b4a.admobwrapper
3 anywheresoftware.b4a.agraham.byteconverter
25 anywheresoftware.b4a.agraham.reflection
75 anywheresoftware.b4a.debug
23 anywheresoftware.b4a.inappbilling3
81 anywheresoftware.b4a.keywords
125 anywheresoftware.b4a.keywords.constants
4 anywheresoftware.b4a.object
401 anywheresoftware.b4a.objects
14 anywheresoftware.b4a.objects.collections
15 anywheresoftware.b4a.objects.drawable
3 anywheresoftware.b4a.objects.streams
173 anywheresoftware.b4a.phone
76 anywheresoftware.b4a.randomaccessfile
28 anywheresoftware.b4a.samples.httputils2
121 anywheresoftware.b4a.shell
11 anywheresoftware.b4a.sql
29 anywheresoftware.b4h.okhttp
15 anywheresoftware.b4j.object
29 anywheresoftware.b4x.objects
37 b4a.example
32 b4a.flm.archiverplus
24 b4a.flm.overlaywdw
162 cn.pedant.SweetAlert
39 cn.refactor.library
130 com.AB.ABExtDrawing
227 com.afollestad.materialdialogs
57 com.afollestad.materialdialogs.color
32 com.afollestad.materialdialogs.commons
30 com.afollestad.materialdialogs.folderselector
63 com.afollestad.materialdialogs.internal
31 com.afollestad.materialdialogs.prefs
14 com.afollestad.materialdialogs.simplelist
4 com.afollestad.materialdialogs.util
23 com.amulyakhare.textdrawable
4 com.amulyakhare.textdrawable.util
7 com.android.vending.billing
79 com.datasteam.b4a.xtraviews
11 com.datasteam.b4a.xtraviews.imports
45 com.desai.vatsal.mydynamictoast
89 com.facebook.rebound
26 com.facebook.rebound.ui
85 com.github.segmentedbarview
15 com.github.tagview
3 com.github.tagview.Models
52 com.github.tagview.Tag
25 com.google.ads
22 com.google.ads.mediation
11 com.google.ads.mediation.customevent
3234 com.google.android.gms
20 com.google.android.gms.actions
3277 com.google.android.gms.ads
12 com.google.android.gms.ads.doubleclick
17 com.google.android.gms.ads.formats
13 com.google.android.gms.ads.identifier
3234 com.google.android.gms.ads.impl
250 com.google.android.gms.ads.internal
222 com.google.android.gms.ads.internal.client
95 com.google.android.gms.ads.internal.formats
155 com.google.android.gms.ads.internal.overlay
51 com.google.android.gms.ads.internal.purchase
194 com.google.android.gms.ads.internal.request
14 com.google.android.gms.ads.internal.reward.client
6 com.google.android.gms.ads.internal.reward.mediation.client
17 com.google.android.gms.ads.internal.util.client
21 com.google.android.gms.ads.mediation
1 com.google.android.gms.ads.mediation.admob
12 com.google.android.gms.ads.mediation.customevent
7 com.google.android.gms.ads.purchase
1 com.google.android.gms.ads.reward.mediation
46 com.google.android.gms.ads.search
52 com.google.android.gms.auth
6 com.google.android.gms.auth.account
18 com.google.android.gms.auth.api
77 com.google.android.gms.auth.api.credentials
23 com.google.android.gms.auth.api.credentials.internal
44 com.google.android.gms.auth.api.proxy
46 com.google.android.gms.auth.api.signin
31 com.google.android.gms.auth.api.signin.internal
3234 com.google.android.gms.base
46 com.google.android.gms.clearcut
99 com.google.android.gms.common
93 com.google.android.gms.common.api
41 com.google.android.gms.common.data
46 com.google.android.gms.common.images
188 com.google.android.gms.common.internal
1 com.google.android.gms.common.internal.safeparcel
4 com.google.android.gms.common.server
12 com.google.android.gms.common.server.converter
33 com.google.android.gms.common.server.response
63 com.google.android.gms.common.stats
22 com.google.android.gms.common.util
34 com.google.android.gms.config.internal
27 com.google.android.gms.dynamic
2 com.google.android.gms.dynamite.descriptors.com.google.android.gms.ads.dynamite
2 com.google.android.gms.dynamite.descriptors.com.google.android.gms.flags
16 com.google.android.gms.flags.impl
14 com.google.android.gms.gass.internal
6 com.google.android.gms.iid
3787 com.google.android.gms.internal
5 com.google.android.gms.location.places
6 com.google.android.gms.measurement
395 com.google.android.gms.measurement.internal
18 com.google.android.gms.phenotype
11 com.google.android.gms.playlog.internal
6 com.google.android.gms.security
26 com.google.android.gms.signin.internal
48 com.google.android.gms.tasks
28 com.google.firebase
60 com.google.firebase.analytics
45 com.google.firebase.auth
49 com.google.firebase.auth.api.model
3239 com.google.firebase.crash
13 com.google.firebase.crash.internal
12 com.google.firebase.crash.internal.config.flag
13 com.google.firebase.crash.internal.service
50 com.google.firebase.iid
33 com.google.firebase.messaging
24 com.google.firebase.remoteconfig
154 com.google.firebase.storage
86 com.joanzapata.pdfview
8 com.joanzapata.pdfview.model
35 com.joanzapata.pdfview.util
20 com.maximussoft.msmaterialdrawer
763 com.mikepenz.google_material_typeface_library
51 com.mikepenz.iconics
599 com.mikepenz.iconics.typeface
1 com.mikepenz.iconics.utils
2 com.mikepenz.iconics.view
160 com.mikepenz.materialdrawer
67 com.mikepenz.materialdrawer.accountswitcher
3 com.mikepenz.materialdrawer.adapter
124 com.mikepenz.materialdrawer.model
14 com.mikepenz.materialdrawer.util
49 com.mikepenz.materialdrawer.view
777 com.pdfjet
13 com.pkmmte.circularimageview
49 com.pnikosis.materialishprogress
6 com.rootsoft.rspopupmenu
4536 com.scsoftstudios.aws
104 com.sctech.awsdesigner
32 com.sctech.famtest
771 com.sctech.sccad2
83 com.sdsmdg.tastytoast
366 com.squareup.okhttp
90 com.squareup.okhttp.internal
133 com.squareup.okhttp.internal.http
1 com.squareup.okhttp.internal.io
243 com.squareup.okhttp.internal.spdy
11 com.squareup.okhttp.internal.tls
10 com.visualnet
3253 com.wdullaer.materialdatetimepicker
214 com.wdullaer.materialdatetimepicker.date
243 com.wdullaer.materialdatetimepicker.time
78 de.amberhome.SimpleActionBar
25 de.amberhome.actionbarhelper
44 de.amberhome.objects
3304 de.amberhome.objects.appcompat
3234 de.amberhome.objects.designsupport
3236 de.amberhome.objects.floatingactionbutton
24 de.amberhome.objects.floatingactionbutton.internal
68 de.amberhome.objects.floatingactionbutton.internal.noa
129 de.amberhome.objects.floatingactionbutton.internal.noa.animation
8 de.amberhome.objects.floatingactionbutton.internal.noa.util
3268 de.amberhome.preferences
168 de.donmanfred
2 default
2 dynamictoastwrapper
28 flm.b4a.animationplus
85 flm.b4a.cache
16 flm.b4a.gesturedetector
32 flm.b4a.maskededittext
218 flm.b4a.ultimatelistview
3334 io.github.douglasjunior.androidSimpleTooltip
1 java.io
28 java.lang
11 java.lang.annotation
1 java.math
7 java.net
2 java.nio
25 java.util
4 java.util.concurrent
3 java.util.logging
4 javax.microedition.khronos.egl
90 me.zhanghai.android.materialprogressbar
1 me.zhanghai.android.materialprogressbar.internal
38 net.xpece.android.colorpicker
3477 net.xpece.android.support.preference
3240 net.xpece.android.support.preference.color
25 net.xpece.android.support.widget
3240 net.xpece.android.support.widget.spinner
4 njdude.cloudprint.sample
10 njdude.fontawesome.lib
83 okio
1 org.json
1 org.mlsoft.MLStr
25 org.mlsoftMLmenu
65 org.vudroid.core
6 org.vudroid.core.events
6 org.vudroid.core.models
3 org.vudroid.core.multitouch
1 org.vudroid.core.utils
4 org.vudroid.pdfdroid.codec
5 smm.cookiecutter
2 tastytoastwrapper
277 uk.co.martinpearman.b4a.pdfjet
21 uk.co.martinpearman.b4a.touchimageview
 

corwin42

Expert
Licensed User
@johndb: Which build tools do you use? For my largest project (uses 31 libraries) adding the Preferences library just adds less than 3000 new methods.
Tested with:
B4X:
 dexdump -f product.apk | grep method_ids_size
Hmm, but it seems to add 18000 fields. Checked with:
B4X:
dexdump -f product.apk | grep field_ids_size
I have no idea how to reduce this. A "hack" may help. If you try to change the package name in the AARs Manifest to the package name of your app this may reduce the size.

Though you seem to add many libraries that do nearly the same stuff. This can be optimized a whole lot.
 
Last edited:

johndb

Active Member
Licensed User
@johndb: Which build tools do you use? For my largest project (uses 31 libraries) adding the Preferences library just adds less than 3000 new methods.
Tested with:
B4X:
 dexdump -f product.apk | grep method_ids_size
Hmm, but it seems to add 18000 fields. Checked with:
B4X:
dexdump -f product.apk | grep field_ids_size
I have no idea how to reduce this. A "hack" may help. If you try to change the package name in the AARs Manifest to the package name of your app this may reduce the size.

Though you seem to add many libraries that do nearly the same stuff. This can be optimized a whole lot.
Thank you for looking into this @corwin42. I have eliminated some of the libraries indicated in the error trace but still have the same problem.
It's time for me to refactor my project as using your material preference library is a must :) I'll post my progress. Thank you again for this excellent library!
 

Erel

Administrator
Staff member
Licensed User
It does look like it adds many fields:

3253 com.wdullaer.materialdatetimepicker
214 com.wdullaer.materialdatetimepicker.date
243 com.wdullaer.materialdatetimepicker.time
3304 de.amberhome.objects.appcompat
3234 de.amberhome.objects.designsupport
3236 de.amberhome.objects.floatingactionbutton
 

corwin42

Expert
Licensed User
The problem is quite good described in this blogpost.

I seems that for each library which references another library which includes Android resources these resources are duplicated with the full qualified name of the package name in the Manifest of the library.
So if several libraries reference AppCompat all resources are added multiple times to the project and this results to this large amount of fields and methods.
 

Erel

Administrator
Staff member
Licensed User
I see it too. It will only happen if your library uses its own resources.
For example AppCompat library uses a single resource file (ac_spinner_row_layout). If you can remove it and then remove the internal AndroidManifest.xml it will save the 3300 fields.
The same is true for Preferences.aar. If you can remove settings.xml (I'm not sure that it is used at all) and remove the internal AndroidManifest.xml file then this library will only add a few fields.
 

corwin42

Expert
Licensed User
Thanks.

For Preferences this should be easy. I think this is really the only resource that is used.
For AppCompat I fear that it will not help because in the code there are several AppCompat Resources accessed. Though I changed that package name in AppCompat Manifest from de.amberhome.objects.appcompat to de.amberhome.objects which I will do for all my other libraries. This eleminates duplicates if the same resources are accessed from different libraries. Maybe this will help a bit.
 

Erel

Administrator
Staff member
Licensed User
For AppCompat I fear that it will not help because in the code there are several AppCompat Resources accessed
Note that you should be able to access resources of Google AppCompat without adding your own resources.
You can use Resources.getIdentifier or use reflection.
 

corwin42

Expert
Licensed User
@johndb : Can you try it again with the latest versions of AppCompat, DesignSupport and Preferences libraries? They should reduce the field count but I don't know if it is enough.

If the limit is still exceeded I'm afraid you will have to wait for the next B4A version which will support multidex feature.
 

johndb

Active Member
Licensed User
@johndb : Can you try it again with the latest versions of AppCompat, DesignSupport and Preferences libraries? They should reduce the field count but I don't know if it is enough.

If the limit is still exceeded I'm afraid you will have to wait for the next B4A version which will support multidex feature.
@corwin42 - Thank you for rejigging your libraries. There has been a significant reduction (over 8,000!) but unfortunately not enough for my application. I'll be revisiting my library use and try to eliminate the libraries that are still using v4 that were developed by other b4A developers as it appears that the V4 libraries are problematic for the overall field count.

B4A version: 6.50
Parsing code. (0.25s)
Compiling code. (1.80s)
Compiling layouts code. (0.10s)
Organizing libraries. (7.08s)
Generating R file. (2.06s)
Compiling debugger engine code. (4.08s)
Compiling generated Java code. (6.60s)
Convert byte code - optimized dex. Error
trouble writing output: Too many field references: 80287; max is 65536.
You may try using --multi-dex option.
 

wimpie3

Well-Known Member
Licensed User
@corwin42 - thanks for you work! This is exactly what I needed for my app. If you get MultiSelectListPreference working, you can expect a donation :)
 
Top