Android Question Handle views outside the Activity?

leitor79

Active Member
Licensed User
Longtime User
Hi,

I have my activity with the views I handle, but I'd like to move some of them outside, to a code module for example, because they're too many and the activity code gets too long and confusing.
For example, in the main activity I load a customlistview, with a personalized layout.... it could be possible to move the customlistview functions and his layout's views outside the main activity?

Regards,
 

emexes

Expert
Licensed User
There should be no problem having Subs in a code module that you call from an activity module, as long as the view objects (buttons, labels, etc) "live" within the activity module and are declared there in Globals (ie, NOT in Process_Globals), and you pass them to the code module sub as parameters rather than (try) access them directly as globals. This doesn't make your activity code less long and confusing, but perhaps it might help by letting you group related code together

Backtracking slightly, though, if the issue is that your activity code is too long and confusing, remember that:

1/ you can use the outlining feature of the code editor to shrink Subs to a single line (or two) when you're not using them
1b/ eg, put cursor in activity module code, then: menu Edit, Outlining, Collapse All
1c/ and similarly, once you've recovered from the heart-attack induced by seeing all your code vanish: menu Edit, Outlining, Expand All

2/ subs are collapsible automatically, but you can also set up your own collapsible outline regions that encompass multiple subs, eg you could have regions for, say, initialization, event handling, activity/form handling, and helper functions, that would group similar functions together and hide them when you're editing other bits of the code.

2/ you can easily navigate between Subs (and modules) using the Modules tab of the Libraries/Logs/etc panel (usually the right-side of the IDE window)
 
Upvote 0

leitor79

Active Member
Licensed User
Longtime User
Thank you very much, emexes!

I'm aware of that options. But one of my problems is that in the main activity I use a side menu with an expandable customlistview (this is; an expandable customlistview with one customlistview on each one of the 3 panels it has), with a main customlistview that load different lists according to the selected option in the menu ("different lists" = "different customlistview's layouts"). So, I have many customlistviews, each one with his layout and, in order to use it, I have to declare all the views they have... and now I'm adding them into the main activity, which leads me to a big and messy code.

Can't I define views to be handled outside the activity?

Thank you?
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Create a class and use this class in each activity.
 
Upvote 0

leitor79

Active Member
Licensed User
Longtime User
Hi DonManfred, thank you for your answer!
I've tried, but I get an exception:

This is my class:

B4X:
Sub Class_Globals
    Private CLV As CustomListView
    Private lblProductoNombreLista As B4XFloatTextField
    Private lblProductoStockLista As B4XFloatTextField
    Private lblPrecioListaLista As B4XFloatTextField
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(oCLV As CustomListView)
    CLV = oCLV
    
End Sub

Public Sub CargarLista(Lista As List)
    
    If Lista.IsInitialized Then
        For Each m As Map In Lista
            Dim p As Panel
            p.Initialize("")
        
            p.SetLayout(2dip, 0, 100%x-4dip, 124dip) <-------------------------- ERROR HERE
            p.LoadLayout("layProductoItemLista") 
            
            CLV.Add(p, m)

I get the following error:

java.lang.NullPointerException: Attempt to invoke virtual method 'int anywheresoftware.b4a.BALayout.getWidth()' on a null object reference

The same error if I load the layout first (as usual).

The same error if I add the panel to the CLV before setting/loading the layout.


Thank you!
 
Upvote 0

emexes

Expert
Licensed User
B4X:
Dim p As Panel
p.Initialize("")

p.SetLayout(2dip, 0, 100%x-4dip, 124dip) <-------------------------- ERROR HERE
p.LoadLayout("layProductoItemLista")

1/ 100%x of... what? try changing the 100%x to be say 320, see if the (well: that) problem goes away
2/ the "" event handler prefix makes me a bit nervous two
 
Upvote 0

leitor79

Active Member
Licensed User
Longtime User
Hi Erel! Thank you for your answer.
I've cut the project and the exception can be reproduced here too.

Thank you!
 

Attachments

  • ErrorClassDemo.zip
    11.1 KB · Views: 125
Upvote 0

leitor79

Active Member
Licensed User
Longtime User
B4X:
Dim p As Panel
p.Initialize("")

p.SetLayout(2dip, 0, 100%x-4dip, 124dip) <-------------------------- ERROR HERE
p.LoadLayout("layProductoItemLista")

1/ 100%x of... what? try changing the 100%x to be say 320, see if the (well: that) problem goes away
2/ the "" event handler prefix makes me a bit nervous two

Hi emexes; thank you for your answer!
I've already used the "" event handler when I don't need to handle events.
Also the 100%x, to indicate full width (of the screen or the container)

Regards!
 
Upvote 0

emexes

Expert
Licensed User
Also the 100%x, to indicate full width (of the screen or the container)

but... in a non-activity, what is that 100% of?

As I understand it: in an activity, it's 100% of the screen (Activity) width.

In a class, you've got the Panel sitting by itself, with no reference point.

I haven't updated to the latest B4A version yet, so I can't reproduce your error exactly, and perhaps I am tripping up on some different issue.
 
Upvote 0

leitor79

Active Member
Licensed User
Longtime User
but... in a non-activity, what is that 100% of?

As I understand it: in an activity, it's 100% of the screen (Activity) width.

In a class, you've got the Panel sitting by itself, with no reference point.

I haven't updated to the latest B4A version yet, so I can't reproduce your error exactly, and perhaps I am tripping up on some different issue.

Yes, that could be the case.
But I've also tried adding the panel to the CLV first. The CLV is within the main activity, so it must have a defined width. But I don't know if that works that way.

Thank you!
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
1. Why is Panel1 in layItem not anchored to both sides?

2. It is a mistake to initialize clsClass from the starter service. It will run in a context of a service instead of an activity. This means that it shouldn't have any UI.

3. Set the panel size before you load the layout:
B4X:
Dim p As Panel
p.Initialize("")
p.SetLayout(2dip, 0, 100%x-4dip, 124dip)
p.LoadLayout("layItem")
 
Upvote 0

leitor79

Active Member
Licensed User
Longtime User
Hi Erel, thank you for your answer! Now it works.
1 - because it's a demo and I didn't do it. Is it better to anchor the views, or to script the view's positions?
2 - I thought that it could be valid because I'm calling the service function from an activity.
3 - Thank you! Could the height (124dip) be taken, in some way, from the layout itself? Like, an auto-height of the clv's item, taken from the layout's base panel height?

Regards!
 
Upvote 0
Top