LoadLayout in a class

stevel05

Expert
Licensed User
Longtime User
I'm probably trying to do something that is not supposed to work, but I have passed the activity to a class and then loaded a layout within the class. The layout is displayed and in the example attached, the DrawBtn_Click method fires as expected, but the EditText1_EnterPressed fails with the error Object should first be initialized.

If I initialize the views within the class, the DrawBtn_Click still fires, but the EditText_EnterPressed does not return the text, presumably a new EditText is created with the initialization.

It would be useful if this would work, but I imagine that it is down to differences in the complexity of the wrappers of each view.
 

Attachments

  • test.zip
    7.2 KB · Views: 258
Last edited:

stevel05

Expert
Licensed User
Longtime User
Great as always

Thanks Erel.

Sent from my HTC Sensation XE with Beats Audio Z715e using Tapatalk 2
 
Upvote 0

EduardoElias

Well-Known Member
Licensed User
Longtime User
The problem is that Activity.LoadLayout looks for the variables in the Activity module and not the current class. So EditText1 variable is not assigned.

It will be fixed in the next update. Note that the layout is built correctly. You can access the EditText by using the Sender keyword in the event.

Erel,

I made a class to add Sliding Panels (followed and example) and this class is responsible to call loadlayout.

What i have found is that all events from the buttons on the layout loaded are not directed to the activity module (there is only one activity)

When i moved the code back to the Activity_Create where it was before the buttons started to fire the click event back again.

I am trying to move things to classes more I can so I can reuse code for other apps.

is it a bug or expected behavior, how to workaround this?
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
What i have found is that all events from the buttons on the layout loaded are not directed to the activity module (there is only one activity)

Fortunately, it's not a bug. If the button is declared in the class, it's not strange that its events are directed to the class, and not to something else. If you want to redirect the event data to the activity, use CallSub.
 
Upvote 0

EduardoElias

Well-Known Member
Licensed User
Longtime User
Fortunately, it's not a bug. If the button is declared in the class, it's not strange that its events are directed to the class, and not to something else. If you want to redirect the event data to the activity, use CallSub.

Thanks,

yes, it makes sense, however how can I create a class that automates most of the environment and then have the events all to the main activity?

It should be something like this: loadlayout(Module, "layoutfile")

THe problem is that I have several layouts, created a class to prepare the sliding panels and load all that, but the events are now going to the class. Is there a way to by code redirect automatically? Previously knowing each one is not an option......

Is it possible to after doing panel.loadlayout to go across all the events of the children of panel and change to main activity?

many thanks!
 
Last edited:
Upvote 0

Informatix

Expert
Licensed User
Longtime User
yes, it makes sense, however how can I create a class that automates most of the environment and then have the events all to the main activity?

It should be something like this: loadlayout(Module, "layoutfile")

THe problem is that I have several layouts, created a class to prepare the sliding panels and load all that, but the events are now going to the class. Is there a way to by code redirect automatically? Previously knowing each one is not an option......!

I'm not sure that I understand what you're trying to do. Could you post a project?
If you want your class to force the activity module to load a specific layout for your activity (so the events are directed to the activity module), use CallSub.
 
Last edited:
Upvote 0

EduardoElias

Well-Known Member
Licensed User
Longtime User
I'm not sure that I understand what you're trying to do. Could you post a project?
A layout is not something loaded by a module, but by a panel (an activity is a panel) to fill it with views.

The source code is really big, let me see if i can explain better:


Sub Activity_Create(FirstTime As Boolean)
Dim Pan(3) As Panel
Pan(0).Initialize("")
Pan(1).Initialize("")
Pan(2).Initialize("")

Pan(0).LoadLayout("tabletpedidos")
Pan(1).LoadLayout("tabletmain")
Pan(2).LoadLayout("tabletpesqitens")

This is the regular way of loading the layout on panels to show up.

However I want the same effect, but calling a class

AppManager.CreateSlidingPanel("tabletpedidos", ...)
AppManager.CreateSlidingPanel("tabletmain")
AppManager.CreateSlidingPanel("tabletpesqitens")

This class, AppManager, has a member CreateSlidingPanel, that:

Public Sub CreateSlindingPanel(LayOut As String, Title As String, Index As Int, Main As Boolean, CreateEvent As Boolean)

If Not(Container.IsInitialized) Then
Container.Initialize
End If

Dim Pan As Panel
Pan.Initialize("")
Pan.LoadLayout(LayOut)
Container.AddPageAt(Pan, Title, Index)

If Main Then
PagerMain = Index
End If
End Sub

That works wonderful, however all the events of the Layout loaded remain on AppManager Class. I want them to go to the main activity. I dont want to define in the code each event and create callsub for each, because this very same AppManager will be used for other apps with totally different layouts. I am trying to create classes that are helpers to create applications, leaving only what is really specific for each application to be implemented on the main activity. Understand the idea?

Many Thanks again!
 
Upvote 0

EduardoElias

Well-Known Member
Licensed User
Longtime User
Use CallSub to load the layout in the activity module:
B4X:
CallSub2(ActivityModule, "LayoutLoaderSub", "LayoutName")

I was thinking on that when suggested and I have tried but did not work:

this is the changed class member:
Public Sub CreateSlindingPanel(Module As Object, LayOut As String, Title As String, Index As Int, Main As Boolean, CreateEvent As Boolean)

If Not(Container.IsInitialized) Then
Container.Initialize
End If

Dim Pan As Panel
Pan.Initialize("")
If SubExists(Module, "OnLoadLayout") Then
CallSub3(Module, "OnLoadLayout", LayOut, Pan)
End If

Container.AddPageAt(Pan, Title, Index)

If Main Then
PagerMain = Index
End If
End Sub

this is in the main activity
Sub OnLoadLayout(Layout As String, Pan As Panel)
Pan.LoadLayout(Layout)
End Sub

I call this on Activity_Create

AppManagerAct.CreateSlindingPanel(Me, "tabletpedidos", "Pedidos", 0, False, True)


The fact is that CallSub is processed on the message loop, and it did not get in time for the rest of the processing. No layouts shows up
 
Upvote 0

EduardoElias

Well-Known Member
Licensed User
Longtime User
Informatix:

I have tried this variant but did not work either:

Public Sub CreateSlindingPanel(Module As Object, LayOut As String, Title As String, Index As Int, Main As Boolean, CreateEvent As Boolean)

If Not(Container.IsInitialized) Then
Container.Initialize
End If


Dim Pan As Panel
Pan.Initialize("")
FAct.AddView(Pan, 0, 0, 0, 0)
Pan.LoadLayout(LayOut)

For i = 0 To FAct.NumberOfViews - 1
If FAct.GetView(i) = Pan Then
FAct.RemoveViewAt(i)
End If
Next

Container.AddPageAt(Pan, Title, Index)

If Main Then
PagerMain = Index
End If
End Sub


My idea was put the panel as parent of the main Activity (FAct) and then LoadLayout after that remove the view from there before adding to the container.

I have no other idea.
 
Upvote 0

EduardoElias

Well-Known Member
Licensed User
Longtime User
And if you add a DoEvents after the LoadLayout ?

Sadly DoEvents is doing nothing, the CallSub3 is not ever getting there (I place a breakpoint and it never happens)

If SubExists(Module, "OnLoadLayout") Then
CallSub3(Module, "OnLoadLayout", LayOut, Pan)
End If
 
Upvote 0

margret

Well-Known Member
Licensed User
Longtime User
@ stevel05

I have been playing with this idea as well. I downloaded your sample to try and see what was going on. It works for me!:icon_clap: Anything I enter in the text box logs just fine when I press the Done button on the keyboard. I tried it on three devices. One with 2.2, one with 2.3 and the last with ICS. I am using 2.22 of b4a. So now I am wondering why mine is working?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Hi Margret,

My original post was made just after V2 came out, this has now been fixed and should work as intended.

Steve
 
Upvote 0

margret

Well-Known Member
Licensed User
Longtime User
@ Steve05

OK, I should of seen the date of the post.

I am trying to make a class that Pops Up a Layout.bal file and passes the events back to the calling Activity. Do you have any idea if it's possible?

I know it can be done if the views of the layout are known. But I would like to make a class that would pass the events of a layout file without having to know the names of the controls. Do you think it is possible to catch any click, enter_pressed, etc. and then pass that to the calling Activity or at least the Tag value of a triggered event?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Not knowing exactly what you want to do with it, I think you would have to either create the layout in the activity and pass the elements as parameters to the class, or create the layout in the class and call a new handling subroutine in the activity, from the standard handler in the class.

Hope this helps
 
Upvote 0

margret

Well-Known Member
Licensed User
Longtime User
I want to load the Layout into a Panel and display the Panel/Layout file. I was hoping to not have to Dim all the views in the Activity and to catch any event that happens on the Layout in the class. Then call a sub in the Activity that will act upon the passed information.

I don't know of any way and there may not be any way to catch an event from the layout loaded in the class other than by the view name. If this would work, it would cut the code down to one line to load a layout and one sub to determine what to do with the event.
 
Upvote 0

margret

Well-Known Member
Licensed User
Longtime User
Hello Steve05,

Thank you for the sample but in it, you know and have dimmed the views of the layout in the class. I am trying to find a way to trigger an event in the class with no dimmed views from the Layout, either in the class or in the Activity.

Say for example I send you a .bal file and you can not open it in the designer to look at what's in the layout, but yet you want to add it to a panel at run time and catch any event from a view on it.

If we could get a list of views and events from the .bal file and had macro substitution it would be a done deal.

I already have the class and the layout showing and closing with animation and it all fine, I just have no events. If I have to add the dimmed objects and object event handlers in the class, there is no benefit to having the class code for this purpose.

Like I said before there may be no way for this to work. I'm just hoping for a Golden Egg I don't know about and someone says, Oh, here's how it's done!!
 
Last edited:
Upvote 0
Top