Android Question Retrieve single UI object from list: Casting fails with Java error

LittleAlf

Member
Licensed User
As a newbie I am not able to overcome the problem described as follows:

Task
I want to access all Edittexts of a view via a list, so that I can easily cycle through them for different testing purposes.

For this, I have created a list in Sub Globals of the corresponding activity. To retrieve a single item of the list, I use a temporary variable of type EditText, and assign the item with its index via the Get-Method. (This should be equivalent to the DirectCast of VisualBasic.)

Unfortunately, at this line the java compiler throws the following error:
java.lang.ClassCastException: anywheresoftware.b4a.objects.EditTextWrapper cannot be cast to android.widget.EditText

Here is now my code. The lines in Activity_Create are for testing purposes to show the error. The error is thrown on the line w = Inputs.Get(0):

B4X:
Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.

   Dim tbxVolumeFlow As EditText
   Dim tbxAltitude As EditText
   Dim tbxPressure As EditText
   Dim tbxTemperature As EditText
   
   Dim Inputs As List   
   Inputs.initialize
   Inputs.AddAll(Array As EditText(tbxVolumeFlow, tbxAltitude, tbxPressure, tbxTemperature))   
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Dim w As EditText
   Msgbox( Inputs.Size,"")
   w=Inputs.Get(0)
   Msgbox( w.text,"")
End Sub

Any help is very much appreciated. Many thanks in advance.

LittleAlf
 

DonManfred

Expert
Licensed User
B4X:
  Dim tbxAltitude As EditText
  Dim tbxPressure As EditText
  Dim tbxTemperature As EditText
   
  Dim Inputs As List   
  Inputs.initialize   
   Dim input As List
   input.Add(tbxVolumeFlow)
   input.Add(tbxAltitude)
   input.Add(tbxPressure)
   input.Add(tbxTemperature)
 
Upvote 0

margret

Well-Known Member
Licensed User
This code you have is:
B4X:
Sub Activity_Create(FirstTime As Boolean)
     Dim w As EditText
     Msgbox( Inputs.Size,"")
     w=Inputs.Get(0)
     Msgbox( w.text,"")
End Sub

It should look like this:
B4X:
Sub Activity_Create(FirstTime As Boolean)
     Dim w As EditText
     w.Initialize("w")
     Msgbox(Inputs.Size, "")
     w.Text=Inputs.Get(0)
     Msgbox(w.Text, "")
End Sub
 
Upvote 0

LittleAlf

Member
Licensed User
Hi DonManfred,
many thanks for your reply. Unfortunately, it does not work. Error: Object should first be initialized (EditText). One question: Why to create a second list? How do the items get transferred to the first list?

Hi Margret,
many thanks. You are right that I forgot to initialize the new EditText object. Unfortunately, I still have no access to the original EditTexts defined in the designer and dimensioned in Sub Global. I just get the message: (EditText) Not initialized.

There must be a way to put views defined in the designer in a list, so that you can access each view AND all its properties via the list!

Best regards,

LittleAlf
 
Upvote 0

LittleAlf

Member
Licensed User
Hi Margret,
the code in the Sub Activity_Create is as follows:
B4X:
Sub Activity_Create(FirstTime As Boolean)
    If (FirstTime) Then
        CalcVolumeflow.Initialize()
    End If
   
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("VolumeflowMain")
   
    ScrollView1.Panel.LoadLayout("VolumeflowInput")
   
    Dim w As EditText
    w.Initialize("")
   
    Msgbox(Inputs.Size, "")
    w.Text = Inputs.Get(0)
    Msgbox(w.text, "")
    ...
End Sub

I still get the message (EditText) Not initialized. when showing the Msgbox(w.text, ""). This means, I cannot get the properties of the EditText, which I stored at position 0 of the list.
 
Upvote 0

warwound

Expert
Licensed User
Is the AddAll method causing the class cast exception?

Change that line, instead of using AddAll and the Array As syntax use the Add method - use Add for each EditText.

There's a thread I started that's related but I can't find it now.

Martin.
 
Upvote 0

LittleAlf

Member
Licensed User
Dear margret, dear warwound,

thanks for your input. I finally got to show at least something. The code being used is as follows:

B4X:
Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.

   Dim tbxVolumeFlow As EditText   Dim tbxAltitude As EditText
   Dim tbxPressure As EditText
   Dim tbxTemperature As EditText

   Dim Inputs As List   
   Inputs.initialize   
End Sub

Sub Activity_Create(FirstTime As Boolean)
   If (FirstTime) Then
     CalcVolumeflow.Initialize()
   End If
   
   'Do not forget to load the layout file created with the visual designer. For example:
   Activity.LoadLayout("VolumeflowMain")
   
   ScrollView1.Panel.LoadLayout("VolumeflowInput")
   
   Inputs.AddAll(Array As EditText(tbxVolumeFlow, tbxAltitude, tbxPressure, tbxTemperature))

   Dim w As EditText
   w.Initialize("")
   
   Msgbox(Inputs.Size, "")
   w.Text  = Inputs.Get(0)
   Msgbox(w.Text, "")

My mistake: It seems that the initialization of views defined in the designer is being done during the LoadLayout method. Now I at least got to see all the properties of the first EditText view being entered in the Inputs list.

But: Now I have the entire properties converted as string and put into the Text property of my newly created EditText 'w'! What I need is a local variable, which holds a reference to the first EditText view put into the Inputs list. Only then I can access all the properties of this EditText by addressing it via w.Text or w.Color for example.

This MUST be possible in B4A, i.e. in Java!

My original approach: w = Inputs.Get(0) still throws the exception java.lang.ClassCastException: anywheresoftware.b4a.objects.EditTextWrapper cannot be cast to android.widget.EditText.

Why do I have the type 'b4a.objects.EditTextWrapper' on one side, and 'android.widget.EditText' on the other?
 
Upvote 0

LittleAlf

Member
Licensed User
I just tested it some more by writing the following test code:

B4X:
   Dim Test As List
   Test.Initialize
   For i = 0 To 9 'create 10 buttons
   Dim Btn As Button
   Btn.Initialize("")
   Btn.Text=i
   Test.Add(Btn)
   Next

   Dim k As Button
   k=Test.Get(0)
   Msgbox(k.Text, "")
   k=Test.Get(1)
   Msgbox(k.Text, "")

This works as expected: The first message box shows '0', and the second one shows '1'.

It seems, that the designer handles the EditTexts differently, than if they are defined in code.

How can this difficulty be overcome?
 
Upvote 0

stevel05

Expert
Licensed User
This works:

B4X:
    Dim Inputs As List
    Inputs.Initialize
    For Each ET As EditText In Array As EditText(EditText1)
        Inputs.Add(ET)
    Next

'    'New editText
    Dim ET As EditText
    'Add the edittext from the list
    ET = Inputs.Get(0)
    Log(ET.Text)

Edittext1 is added to a layout.
 
Last edited:
Upvote 0

warwound

Expert
Licensed User
If you change this line:

B4X:
Inputs.AddAll(Array As EditText(tbxVolumeFlow, tbxAltitude, tbxPressure, tbxTemperature))

To:

B4X:
Inputs.Add(tbxVolumeFlow)
Inputs.Add(tbxAltitude)
Inputs.Add(tbxPressure)
Inputs.Add(tbxTemperature)

Does that fix the ClassCastException?

I had a similar problem where 'wrapped' objects were becoming 'unwrapped' objects when using the List AddAll method: http://www.basic4ppc.com/android/forum/threads/passing-b4a-list-as-arraylist.23371/#post-135851.

Martin.
 
Upvote 0

LittleAlf

Member
Licensed User
Dear warwound,

thank you for your comment: It is correct. Adding the EditTexts one after one does the trick.

In parallel I found another, more elegant way of doing it (in the beginner's guide :oops:!):

B4X:
Sub Globals
   Dim tbxVolumeFlow As EditText
   Dim tbxAltitude As EditText
   Dim tbxPressure As EditText
   Dim tbxTemperature As EditText
   
   Dim Inputs() As EditText  
End Sub

Sub Activity_Create(FirstTime As Boolean)
   'Do not forget to load the layout file created with the visual designer. For example:
   Activity.LoadLayout("VolumeflowMain")
   
   Inputs = Array As EditText(tbxVolumeFlow, tbxAltitude, tbxPressure, tbxTemperature)
   
   Dim tmpEditText As EditText
   
   Msgbox(Inputs.Length, "")
   tmpEditText  = Inputs(0)
   Msgbox(">" & tmpEditText.Text & "< - " & tmpEditText.Height, "")
End Sub

It seems like it is better to go with Arrays in B4A for objects (at least views, which are created in the designer). Even though B4A transforms arrays into lists, the "unwrapping" of B4A objects does not seem to happen as easily with arrays than with list.

Many thanks to everybody who helped me on this.

LittleAlf
 
Upvote 0

warwound

Expert
Licensed User
You could also have tried:

B4X:
 Inputs.AddAll(Array As Object(tbxVolumeFlow, tbxAltitude, tbxPressure, tbxTemperature))

That's untested.

Martin.
 
Upvote 0
Top