Android Question How to convert string array to CharSequence parameter?

JohnC

Well-Known Member
Licensed User
I am trying to display a MaterialDialog that includes a list of strings.

The example code looks like this:
B4X:
Builder.Title("Months and Days")
Builder.Items(Array As String("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"))
Builder.ItemsCallback
Builder.NegativeText("Cancel")
Builder.Show
But I need to pass a dynamic string array to the routine instead of hard-coded strings in the above example code.

I tried creating a simple String array:
B4X:
Dim D(3) as string
D(0) = "One"
D(1) = "Two"
D(2) = "Three"
...
Builder.Items(D)
But I get a huge exception on the Builder.Show line that ends with:

B4X:
android.view.InflateException: Binary XML file line #1: Error inflating class <unknown>
    at android.view.LayoutInflater.createView(LayoutInflater.java:640)
    at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55)
    at android.view.LayoutInflater.onCreateView(LayoutInflater.java:689)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:748)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:483)
The pop-up type description of the parameter says "Items (ItemArray() as CharSequence)"

So, I tried using the CSBuilder:

B4X:
Dim cs As CSBuilder
 
cs.Initialize
 
cs.Append("one")
cs.Append("two")
cs.Append("three")

Builder.Items(cs)
But I got this error during compile:

B4X:
src\com\omnisoft\btgallery\directoryview.java:617: error: incompatible types: SpannableStringBuilder cannot be converted to CharSequence[]
_builder.Items((java.lang.CharSequence[])(_cs.getObject()));
How can I pass a dynamic set of strings to the dialog's "Items" parameter?

I know it will probably end up being a simple solution, but I just hate all the time "syntax issues" like this waste with all the trial and error attempts I've made.
 
Last edited:

JohnC

Well-Known Member
Licensed User
I would like to generate the dialog using the MaterialDialogs lib because I use this lib for other dialogs in the app (like progress dialog) and would like to keep things consistent without having to rewrite/change the look at this time.

Besides, I would like to learn how to resolve this issue in case I run into it again or anybody else running into this so it will save them time too.

So, it would be greatly appreciated if you could show me how to resolve this error :)
 

JohnC

Well-Known Member
Licensed User
Putting aside this particular library.....I just want to know how to convert a string array into a CharSequence.

For example, when I try the CSBuilder method, why is the B4A compiler thinking that the CSBuilder is generating a "SpannableStringBuilder" type and not a CharSequence type?
 
Last edited:

emexes

Well-Known Member
Licensed User
I haven't used MaterialDialog library either, but it looks like your code:
B4X:
Dim cs As CSBuilder
 
cs.Initialize
 
cs.Append("one")
cs.Append("two")
cs.Append("three")

Builder.Items(cs)
is creating a single CharSequence and passing it to Builder. Perhaps this might work:
B4X:
Dim csa(3) As CSBuilder

csa(0).Initialize.Append("One")
csa(1).Initialize.Append("Two")
csa(2).Initialize.Append("Three")

Builder.Items(csa)
where csa is an array of CharSequences, which Builder might accept. If it doesn't, try adding () to csa ie csa(), see if that helps.
 

JohnC

Well-Known Member
Licensed User
Hi emexes,

When I tried my csbuilder way, the compiler threw an immediate error about csbuilder type being incompatible with the builder's CharSequence type (meaning it was a compile error, not a run time error.)

So, I was thinking that your code might not make a difference because the compiler would still see the incompatible types, but the compiler did run without errors using your code - probably because turning the cs into an array turned it into an "object" that the compiler then did not find any immediate incompatibilities with and allowed the app to be compiled.

But, when I run your method I get this runtime error:
B4X:
java.lang.ClassCastException: anywheresoftware.b4a.objects.CSBuilder[] cannot be cast to java.lang.CharSequence[]
So, it still seems the CSBuilder is not generating the "CharSequence" type that the Builder is expecting.

(also, adding () or a (0) did not work)
 

emexes

Well-Known Member
Licensed User
So, it still seems the CSBuilder is not generating the "CharSequence" type that the Builder is expecting.
Hmm.

How about this reasoning?... apparently a CSBuilder can be assigned to Label.Text, and Label.Text is said to be a String, so maybe java.lang.CharSequence is the same as, or compatible with, a B4A String.

So if you've still got that test code about, try changing it to:
B4X:
Dim csa(3) As CSBuilder              'no change

csa(0).Initialize.Append("One")      'no change
csa(1).Initialize.Append("Two")      'no change
csa(2).Initialize.Append("Three")    'no change

Dim sa(3) As String                  'added
sa(0) = csa(0)                       'added
sa(1) = csa(1)                       'added
sa(2) = csa(2)                       'added

Builder.Items(sa)                    'changed to sa from csa
 

emexes

Well-Known Member
Licensed User
did you tried to use a List of CSObjects?
Manfred's List instead of my Array might well be the answer too. Although the error message did refer to java.lang.CharSequence[] which sure looks like an array to me. But whenever I think one thing and Manfred thinks different, usually* the shortest way to the right answer is for me switch to whatever Manfred says :)


* usually... but not always ;-)
 

JohnC

Well-Known Member
Licensed User
did you tried to use a List of CSObjects?
B4X:
dim l as list
l.initialize
Dim cs As CSBuilder
l.Add(cs.Initialize.Color(Colors.Red).Append("Hello World!").PopAll)
l.Add(cs.Initialize.Append("Two").PopAll)
Builder.Items(l)
I tried this:
B4X:
Dim l As List
l.initialize
Dim cs As CSBuilder
l.Add(cs.Initialize.Append("One").PopAll)
l.Add(cs.Initialize.Append("Two").PopAll)
l.Add(cs.Initialize.Append("Three").PopAll)
Builder.Items(l)
And got this error during COMPILATION:
B4X:
src\com\omnisoft\btgallery\directoryview.java:588: error: incompatible types: List<Object> cannot be converted to CharSequence[]
_builder.Items((java.lang.CharSequence[])(_l.getObject()));
 

JohnC

Well-Known Member
Licensed User
Hmm.

How about this reasoning?... apparently a CSBuilder can be assigned to Label.Text, and Label.Text is said to be a String, so maybe java.lang.CharSequence is the same as, or compatible with, a B4A String.

So if you've still got that test code about, try changing it to:
B4X:
Dim csa(3) As CSBuilder              'no change

csa(0).Initialize.Append("One")      'no change
csa(1).Initialize.Append("Two")      'no change
csa(2).Initialize.Append("Three")    'no change

Dim sa(3) As String                  'added
sa(0) = csa(0)                       'added
sa(1) = csa(1)                       'added
sa(2) = csa(2)                       'added

Builder.Items(sa)                    'changed to sa from csa
I tried your code, and because the variable passed to builder was a string array, it gave the same error I originally received when I tried to pass a string array in my OP:
B4X:
android.view.InflateException: Binary XML file line #1: Error inflating class <unknown>
 

JohnC

Well-Known Member
Licensed User
OK, I figure out the problem...

For kicks and giggles, I tried just pasting the sample code in as a test:

B4X:
Builder.Items(Array As String("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"))
And it gave me the same error as when I tried to pass a string array.

I then compared my code to the demo code for the MaterialDialogs and everything seemed ok.

But then I found in the demo's manifest it defined a style:
B4X:
SetApplicationAttribute(android:theme, "@style/MyAppTheme")

CreateResource(values, theme.xml,
<resources>
    <style name="MyAppTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">#FF2196F3</item>
        <item name="colorPrimaryDark">#007CF5</item>
        <item name="colorAccent">#FFFF3D00</item>
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
        <item name="windowActionModeOverlay">true</item>
    </style>
</resources>
)
So, I added it to my app manifest and sure enough that fixed it!

The strange thing is that my app also includes a progress dialog using this same materialdialogs library and it worked fine without a defined style.

So, ultimately you can pass a string array and it will work:
B4X:
Dim D(3) as string
D(0) = "One"
D(1) = "Two"
D(2) = "Three"
...
Builder.Items(D)
 
Top