Android Question How do I reliably identify Labels (and other views)?

MrKim

Well-Known Member
Licensed User
Longtime User
I'm frustrated. Why are we able to write code that does not work? I find myself spending hours on things that should be simple. This is just one example
I tried several variations of this:
B4X:
    For Each VV As View In GroupLbl.Parent.GetAllViewsRecursive
        If VV Is Label Then
            Dim V As Label = VV
            Log(GetType(VV) & "  " &  V.Text)

            If V.Text.StartsWith("Allow") Then V.Visible = False
            V.TextColor = xui.Color_LightGray
        End If
    Next

As you can see from the results below NOTHING returns a label or "label" (the labels are the ones that say City/State/Zip/etc.)

B4X:
android.widget.EditText  00001 Anywhere Ave.
android.widget.TextView  Address
android.widget.TextView  Test2
android.widget.EditText  MN
android.widget.TextView  State
android.widget.EditText  99936985
android.widget.TextView  Zip
android.widget.EditText  Everyhere2
android.widget.TextView  City
android.widget.TextView  Allow Pictures
android.widget.TextView  GeoFence
android.widget.Button  Save Changes
android.widget.EditText  Address Line 2 Test
android.widget.TextView  Address 2
android.widget.TextView  Comments
android.widget.EditText  Comments Test

I found code from 2012 that says If Is Label doesn't work, use Gettype well, Ok, I did that but it doesn't work either as you can see from the above listing, So more research and I find code from 2015 that recommends If Is Label again so I am thinking "is this now supposed to work? What am I missing?" The code above was VV As B4XView so I am thinking that is the problem so i switched it.

Honestly, if I need to tag the labels or put them in an array I can do that but that is not the clean simple way and involves remembering to do it later when new controls are added.

This is a B4X pages project so it needs to work in B4A/i/J. It seems to work ok in B4i, haven't checked b4A, B4A returns the above.

So, what is the recommended procedure for reliably returning the type of view in B4A/i/J?
 

MrKim

Well-Known Member
Licensed User
Longtime User
Why aren't you using B4XView? Especially if it should be cross platform.

"VV Is Label" worked in 2012 and it works in 2021. You do need to be aware that it will also return true to views that extend label such as EditText, Button and others.
GetType returns the native type. It will never return "Label".
I am using B4Xviews as mentioned, the code above was one of many experiments trying to identify ONLY Labels.

Your missing my point. It does me no good if it also returns True for other types. To my simple mind if it returns other things as well then it is not working correctly. I want to set colors but ONLY for labels. I think 'Is Label' is horribly misleading. Please try to remember that many of us chose B4X to avoid the complexities of learning about classes and subclasses. I just want to know how to reliably determine what type of View I am dealing with. I tried setting the tag in designer but that evidently isn't valid either as it doesn't seem to be available in code. I mean if I need to declare every single View in my layout and set them one at a time in code I can do that - in this case it certainly would have been faster, it just seem(ed) so obvious to be able to identify a view by type and set it. Evidently that is not the case.

So then in re-reading the post from 2012 does "android.widget.TextView" = Label? Or are there other things that will return this as well?

Again, some of us have no interest (really, more accurately in my case no time) in learning about classes and subclasses. I am just a dumb database programmer trying to do a job. B4X is such an incredible tool, I honestly would not even have attempted Android programming if I had to learn java, let alone Apple. IT makes so many things simple, but at the same time some things which seem like they really should be simple, are not. Or perhaps a better term is confusing.
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Change the order of views to test.
As there are some Objects which are based on Label you need to check for them first.


Edittexts, Buttons, others and last have a default check for a label....

Something like (note that it needs more adaptions)
B4X:
For Each VV As View In GroupLbl.Parent.GetAllViewsRecursive
  if VV is Button then
  else If VV Is EditText Then

  ' Problably you need to check for other Objects too!
   
  else
    Dim V As Label = VV
    Log(GetType(VV) & "  " &  V.Text)
    If V.Text.StartsWith("Allow") Then V.Visible = False
    V.TextColor = xui.Color_LightGray
  End If
Next
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
Also, if I may, why not make use of the Tag property here? And instead of checking for view type, check the tag!
 
Upvote 0

udg

Expert
Licensed User
Longtime User
@MrKim : if you're curious about the subject, have a glimpse of the first rows of the following links:
TextView: https://developer.android.com/reference/android/widget/TextView
Button: https://developer.android.com/reference/android/widget/Button
EditText: https://developer.android.com/reference/android/widget/EditText

In particular look at the list of components under "Known direct/indirect subclasses" for each. That will clearly show the hierarchy on which they're built and will, for example, explain why a button is a "label" (i.e TextView).
As @klaus and @DonManfred explained, use GetType(View) to associate a componente to its Android base type.
 
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
Also, if I may, why not make use of the Tag property here? And instead of checking for view type, check the tag!
If you look at my response to Erel's post, I tried that. I mentioned that I tried setting the tag in designer but I wasn't seeing it in code. Plus, there is the complexity of converting it. I tried setting it to "Lbl" but you can't just test the tag for that with .EqualeIgnoreCase. You have to convert it to a string first. But as I mentioned, setting it in designer it didn't seem to show up in code.
 
Last edited:
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
With GetType(View) you get:
Button > android.widget.Button
EditText > android.widget.EditText
Label > android.widget.TextView
Which comes back around to my complaint. If a label is an android.widget.TextView why is it 'Is Label' and not 'Is android.widget.TextView'?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
GetType returns the native view. As it happens the native view of Label is android.widget.TextView in B4A. Using GetType to find your labels is a mistake.

If you look at my response to Erel's post, I tried that. I mentioned that I tried setting the tag in designer but I wasn't seeing it in code. Plus, there is the complexity of converting it. I tried setting it to "Lbl" but you can't just test the tag for that with .EqualeIgnoreCase. You have to convert it to a string first. But as I mentioned, setting it in designer it didn't seem to show up in code.
There is no problem to set the tag with the designer.

Which comes back around to my complaint
Post questions, not complaints. Nothing good will come out of complaints.
If you have any technical question then please start a new thread and I'll be happy to help you. Focus on the technical side.
 
Upvote 0
Top