Android Question No access the properties of my class

osdiarte

Member
Licensed User
Longtime User
I can't access the properties (cliCod as Int and cliClon as Int) of my "ClienteTarjeta" class to which I load a layout "ClienteCard2"
Modulo Clase ClienteTarjeta:
'Custom View class
#Event: ExampleEvent (Value As Int)
#DesignerProperty: Key: BooleanExample, DisplayName: Boolean Example, FieldType: Boolean, DefaultValue: True, Description: Example of a boolean property.
#DesignerProperty: Key: cliClon, DisplayName: Clonado veces, FieldType: Int, DefaultValue: 0, MinRange: 0, MaxRange: 100, Description: esta propiedad representa las veces que se clono o replico un cliente. Mas usado para agregar un nuevo cliente Ocasional(1) y poder replicarlo para otros
#DesignerProperty: Key: cliCod, DisplayName: Codigo del cliente, FieldType: Int, DefaultValue: 0, MinRange: 0, MaxRange: 100, Description: Código del Cliente

Sub Class_Globals
    Private mEventName As String 'ignore
    Private mCallBack As Object 'ignore
    Private mBase As Panel 'B4XView 'Panel
    'Private Const DefaultColorConstant As Int = -984833 'ignore
    
    'Private ShapeCli As Panel ' As B4XView ' No es necesario definirlo, al parecer se define cada vez que se va agregar
    Private lbconcre,lbruc,lbnom,lbmonto,lbcod,lbclon,lbdir,lbmeta,lbprop As Label ' lbconcre,
    Private lbResumCli As Label
    Private lbResumTot As Label
    Private lblAction1 As Label

    Public cliClon As Int = 0
    Public cliCod As Int =0

End Sub

Public Sub Initialize (Callback As Object, EventName As String ,fichaCliente As Map)
    mEventName = EventName
    mCallBack = Callback
End Sub

Public Sub DesignerCreateView (ShapeCli As Panel ,curClientes As Map, Props As Map)
    mBase = ShapeCli
    Sleep(0)
    mBase.LoadLayout("ClienteCard2")
    
    cliClon = curClientes.Get("cli_clon")
    cliCod  = curClientes.Get("cli_codigo")

    Dim xConCre As Int = curClientes.Get("cli_concre")
    If xConCre=2 Then
        lbconcre.Text = "CR"
    Else
        lbconcre.Text = "CO"
    End If

    lbnom.Text = curClientes.Get("cli_descri")

    If curClientes.Get("cli_contacto")<>Null Then
        lbprop.Text = curClientes.Get("cli_contacto")
    Else
        lbprop.Text = ""
    End If

    If curClientes.Get("cli_ruc")<>Null Then
        lbruc.Text = "RUC:" & curClientes.Get("cli_ruc")
    Else
        lbruc.Text = "RUC:?"
    End If

    Dim elmonto As Double =curClientes.Get("total")
    lbmonto.Text = NumberFormat2(elmonto,0,0,0,False) ' xPriceDigDecimal,xPriceDigDecimal,False)

    lbdir.Text = curClientes.Get("cli_direcc")
    '
    mBase.Tag = Me ' " soy el tag de ClienteTarjeta"
    
End Sub

Public Sub GetBase As Panel
    Return mBase
End Sub

When I receive click the view LblAction1 I want to access all the data of that card, both the views and the custom properties that I added. I already managed to access the views by GetView () but I can't access the properties of my class. What am I doing wrong?
Modulo activity RutaCliente:
Sub lblAction1_Click
    Dim index As Int = CLVrutacli.GetItemFromView(Sender)
    Log($"Action 1 clicked. Index: ${index}"$)
    
    Dim pnlItem As B4XView = CLVrutacli.GetPanel(index)  ' Reproduce el objeta tarjetaCliente seleccionado
    Log("pnlItem:" & pnlItem.NumberOfViews &" vistas")
    Dim tarjeta As B4XView = pnlItem.GetView(0)
    Log("Vistas de tarjeta:" & tarjeta.NumberOfViews)
    Dim iLblnom As Label = tarjeta.GetView(1) ' 0:lbconcre 1:lbnom 2:lbruc 3:lbprop 4:lbdir 5:lbmonto 6:lblAction1
    Log("Nombre:" & iLblnom.Text)
    Log("Parent:" & iLblnom.Parent)
    
    Log("panel.tag")
    Log(pnlItem.Tag)
    
    Log("tarjeta.tag")
    Log(tarjeta.Tag)

    Dim tarjeta2 As ClienteTarjeta = pnlItem.GetView(0)
    Log("tarjeta2")
    Log(tarjeta2.cliCod)

End Sub

Evento Click en el activity:
Sub lblAction1_Click
    Dim index As Int = CLVrutacli.GetItemFromView(Sender)
    Log($"Action 1 clicked. Index: ${index}"$)
    
    Dim pnlItem As B4XView = CLVrutacli.GetPanel(index)  ' Reproduce el objeta tarjetaCliente seleccionado
    Log("pnlItem:" & pnlItem.NumberOfViews &" vistas")
    Dim tarjeta As B4XView = pnlItem.GetView(0)
    Log("Vistas de tarjeta:" & tarjeta.NumberOfViews)
    Dim iLblnom As Label = tarjeta.GetView(1) ' 0:lbconcre 1:lbnom 2:lbruc 3:lbprop 4:lbdir 5:lbmonto 6:lblAction1
    Log("Nombre:" & iLblnom.Text)
    Log("Parent:" & iLblnom.Parent)
    
    Log("panel.tag")
    Log(pnlItem.Tag)
    
    Log("tarjeta.tag")
    Log(tarjeta.Tag)

    Dim tarjeta2 As ClienteTarjeta = pnlItem.GetView(0)
    Log("tarjeta2")
    Log(tarjeta2.cliCod)

End Sub

Cuando click obtengo este error :

1642073697804.png
 

Attachments

  • clietnecard2.bal
    5.5 KB · Views: 90
  • ClienteTarjeta.bas
    3.3 KB · Views: 86
  • RutaCliente.bas
    10 KB · Views: 92
  • 1642073980469.png
    1642073980469.png
    57 KB · Views: 72

klaus

Expert
Licensed User
Longtime User
How did you generate the CustomView ?
Because this line ist strange!
B4X:
Public Sub Initialize (Callback As Object, EventName As String ,fichaCliente As Map)
When you create a new CustomView(XUI) you get this:
B4X:
Public Sub DesignerCreateView (Base As Object, Lbl As Label, Props As Map)
The properties are in the Props Map.
Therefor you should get then with:
B4X:
   cliClon = Props.Get("cliCllon")
   cliCod  = Props.Get("cliClodigo")
And not:
B4X:
   cliClon = curClientes.Get("cli_clon")
   cliCod  = curClientes.Get("cli_codigo")
Then the keys in DesignerProperty you set the keys to cliClon and cliCod
B4X:
#DesignerProperty: Key: cliClon, DisplayName: Clonado veces, FieldType: Int, DefaultValue: 0, MinRange: 0, MaxRange: 100, Description: esta propiedad representa las veces que se clono o replico un cliente. Mas usado para agregar un nuevo cliente Ocasional(1) y poder replicarlo para otros
#DesignerProperty: Key: cliCod, DisplayName: Codigo del cliente, FieldType: Int, DefaultValue: 0, MinRange: 0, MaxRange: 100, Description: Código del Cliente
And you try to read them with other keys: cli_clon and cli_codigo why?

When you develop CustomViews you should not modify these two Sub calls, leave them as they are :
B4X:
Public Sub Initialize (Callback As Object, EventName As String)
Public Sub DesignerCreateView (Base As Object, Lbl As Label, Props As Map)

You may have a look at the B4X Custom views booklet.
 
Upvote 0

osdiarte

Member
Licensed User
Longtime User
Thanks for answering.
I corrected the errors that were indicated to me. I followed the manual B4X Custom views booklet and applied them.
Create a small project and upload it here.
Now I have error this error java.lang.RuntimeException: Object should first be initialized (Label).. It seems that my class does not link with my layout because it asks me to initialize the views.
 

Attachments

  • Files.zip
    98.6 KB · Views: 101
  • RutaClientes.zip
    6.2 KB · Views: 100
Upvote 0

klaus

Expert
Licensed User
Longtime User
Here you are.
There were quite some mistakes in your code.
I did not see the CustonListView on the screen, tested to add other panels but nothing on the screen.
Then I removed the CustonListView from the layout and added a new one, and then it was displayed on the screen, I do not know why.
Then I made modifications in the code and in the layouts.

Your approach of the problem seems very complicated to me.
Why do you use a CustomView for the entries in the CustonListView ?
Why do you use an intermediate Map to transfer the data ?
I would do all this, generating the views of the entry and fill their data, directly in the code where you fill the CustomView.

When you upload a project you should use Export As Zip in the File menu instead of zipping the project files and the Files folder separately.

1642242438232.png


Attached a modified project.
 

Attachments

  • RutaClientesNew.zip
    111.4 KB · Views: 92
Upvote 0

osdiarte

Member
Licensed User
Longtime User
Thanks Klaus and everyone who collaborated.
I adapted your example to my project and it worked.
I'm experimenting to use the maintainability that a class gives you combined with layout for ease of design, too. With the properties that I add to the class, it helps me avoid using Lists.
I prefer to pass Map as an argument because if I need to pass more data from the client, I add it without having to modify the class code.
 
Upvote 0
Top