Android Question Brainstorming: How to solve my problem.

Blueforcer

Well-Known Member
Licensed User
Longtime User
Hello together,

im struggeling for days solving my problem.

I really want to use B4Xpages, because its easier to keep the views when the app is rotating/resizing.
The Maingoal is to have a app framework like the picture below.
So the header and sidebar is static and the B4XPages are rendered in the content panel
The Sidebar is made with the B4XDrawer.

1645537291317.png


You need to know:
The GUI is mainly generated dynamically by a json at the start of the application. This json sets all the sidebar items, theme, content of each b4xpage and so on.
Also my custom backend is genereated by json. For example logics, hardwarebus and so on.
The App will run on an industrial panel and will act as a PLC to control a bunch of busdriven devices for watertreatment and electrolysis. So its very important that the app will always run for 100%, even if the app is in the background or changing the orientation.


Try 1:
Load the layout in the activity with b4xdrawer and header, and initialize the B4XPagesManager with the ContentPanel

Advantages:
  • The Sidebar and Header is always visible and instanced only once
  • I can switch the B4XPage by choose one from the sidebar, without breaking the user experience (New page shown up in the background, after some millisecons the sidebar closes animated.
Disadvantages
  • If i rotate the phone, it destroys all the views in the main activity, and need to setup again. This would destroy several classes( (for example some intelligent in the header) wich needs working in the background all the time, without too loose it for a short time. Also the Sidebar is destroyed and needs to build up again (this is not a layout, its generated from a json). Also all the color theming is gone and need to set again

Try 2:
Building a class wich contains the whole framework and instanciate and place it to every singe B4Xpage

Advantages:
  • All views, and classes are kept at anytime
Disadvantages
  • The intelligent views are running multiple times, but they shouldn't. wich could cause a much higher RAM usage as needed for some classes.
  • The B4XDrawer removes immediately when you call a new b4xpage. This doesnt look nice
  • You need to parse all current states of the sidebar to every b4xpage in order to keep the highlighted Item etc.



As you can see, i tried the only both variants i could find here in the forum.
But im not happy with any of the results.
Does anyone knows a even better way to reach my goal?

i really appreciate any of your help
 
Last edited:

Sandman

Expert
Licensed User
Longtime User
I'm not sure how much this will help, but just the other day I was thinking that it would be nice if I could specify the root object for B4XPages. That way I could easily place bottombuttons (example) and other things outside the root panel. I haven't looked into B4XPages to see if it would be simple (or even possible) already.

As for the rotation you want to have I have nothing to help with, sorry.

(Sidenote: That's not a great topic you set for this thread. You might want to summarize the content in the future and use that as topic. It will help your post get more exposure and attract people that have something to say on the topic.)
 
Upvote 0

Blueforcer

Well-Known Member
Licensed User
Longtime User
I'm not sure how much this will help, but just the other day I was thinking that it would be nice if I could specify the root object for B4XPages. That way I could easily place bottombuttons (example) and other things outside the root panel. I haven't looked into B4XPages to see if it would be simple (or even possible) already.

As for the rotation you want to have I have nothing to help with, sorry.

(Sidenote: That's not a great topic you set for this thread. You might want to summarize the content in the future and use that as topic. It will help your post get more exposure and attract people that have something to say on the topic.)
I done this in Try1
you can specify any root for your B4Xpages
B4X:
Dim pm As B4XPagesManager
pm.Initialize(ContentPanel)
 
Upvote 0

Sandman

Expert
Licensed User
Longtime User
I done this in Try1
you can specify any root for your B4Xpages
B4X:
Dim pm As B4XPagesManager
pm.Initialize(ContentPanel)
How about that, I had missed that - thanks. Erel said it's not cross platform, but didn't specify more. Do you happen to know more? Does it work in B4i? B4J?
 
Upvote 0

Blueforcer

Well-Known Member
Licensed User
Longtime User
How about that, I had missed that - thanks. Erel said it's not cross platform, but didn't specify more. Do you happen to know more? Does it work in B4i? B4J?
Im sure it will work in B4J and its RootPane. Dont know about B4i.

But yeah crossplatform would be great, maybe it needs deeper modifications in the B4XPageManager Class.
Its also not possible to create another B4XPageManager inside an existing one.
That would solve my problem. In this case i would build the GUI framework in the B4XMainPage and create a new B4XPage instance on the contentpanel.

Maybe at the end i need to write my own B4XPage Lite class, wich can replace the content from with generated views from classes
 
Upvote 0

Sandman

Expert
Licensed User
Longtime User
Its also not possible to create another B4XPageManager inside an existing one.
I don't fully understand your situation so I might be talking stupid now, but it kind of seems to me that it would be possible to create another B4XPageManager inside an existing one.

Not by default perhaps, but remember that B4XPageManager is just another b4xlib. If you duplicate it, unpack it and rename things so you have a (more or less) clone called BlueforcerPageManager class that you then can use inside B4XPageManager - wouldn't that work? In any case it shouldn't take more than an hour to test, I suppose.

Maybe at the end i need to write my own B4XPage Lite class
Yeah, perhaps. Or perhaps you can just do what I said above, so you don't need to put effort into making a Lite version?
 
Upvote 0

Blueforcer

Well-Known Member
Licensed User
Longtime User
I don't fully understand your situation so I might be talking stupid now, but it kind of seems to me that it would be possible to create another B4XPageManager inside an existing one.

Not by default perhaps, but remember that B4XPageManager is just another b4xlib. If you duplicate it, unpack it and rename things so you have a (more or less) clone called BlueforcerPageManager class that you then can use inside B4XPageManager - wouldn't that work? In any case it shouldn't take more than an hour to test, I suppose.


Yeah, perhaps. Or perhaps you can just do what I said above, so you don't need to put effort into making a Lite version?

I need to have a look at this, maybe it could work. Thanks
 
Upvote 0

Blueforcer

Well-Known Member
Licensed User
Longtime User
But wait a moment..
Because i only need one "Main" framework maybe its easier to create just a class wich holds the framework and use the B4XPageManager in this one.
I just need to make sure that the class will not be destroyed from the mainactivity, maybe declare it in the Process_Globals should work
 
Upvote 0

Blueforcer

Well-Known Member
Licensed User
Longtime User
Nope, its detected as an Activity Object and cant be declared under Process_Globals

All of the views for example cannot be declared as process variables.
The reason is that we do not want to hold a reference to objects that should be destroyed together with the activity.

But this is exactly what i want :) Is there a workaround for this?
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
I like your approach with a json driven model, and the GUI interface is pretty simple.
I am not sure what you mean by

So its very important that the app will always run for 100%, even if the app is in the background or changing the orientation.
I really want to use B4Xpages, because its easier to keep the views when the app is rotating/resizing.

Even without pages you can fix orientation. With B4XPages you will be committed to an orientation.
If you want to be responsive to a change in orientation, you will need to handle the Views, no matter what.

That being said, let's assume you can insist on landscape, since that seems the most natural looking at your layout.

I can see this working with just one B4XPage, with a content panel that get loaded in response to the side bar actions.
The varying contents do not need to be separate pages, I think? I so, everything is much simpler.

Since B4XPages never pause, your 100% is more achievable.
 
Last edited:
Upvote 0

Blueforcer

Well-Known Member
Licensed User
Longtime User
I am not sure what you mean by


Even without pages you can fix orientation. With B4XPages you will be committed to an orientation.
If you want to be responsive to a change in orientation, you will need to handle the Views, no matter what.

That being said, let's assume you can insist on landscape, since that seems the most natural looking at your layout.

I can see this working with just one B4XPage, with a content panel that get loaded in response to the side bar actions.
The varying contents do not need to be separate pages, I think? I so, everything is much simpler.
The views are all customviews wich are working by its own in the background. Like listening to register states etc. So if the views are getting destroyed they stop working.
This does not happen with b4xpages. I only need to change the displayvariants of the existing views with the resize event.
And a project can contains hundreds of different pages if the customer needs it for any reason. So B4Xpages will make it much more simpler.

On the main industiral panel it will running in landscape for sure. But later there will be the same app on desktop an iOS. if so the app runs in client mode and connects to the master panel. In this case changing the orientation is important for the user expierience . It looks good in both ways (this is jsut democontent:))

1645544883185.png


1645544889998.png
 
Last edited:
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
I see. You can't dynamically load the layouts, since the underlying class instances need to operate continually, even when not visible.
That's why you need separate pages.

The problem (one you haven't mentioned) is that in B4Xpages you have to commit to a orientation at the start of the program.
That is one of the reasons B4Xpages doesn't pause. However, if you would be satisfied with this, you can set the orientation
early in the program (before initializing B4XPageManager) to whatever orientation the user is holding the device.)
If interested I can show you how to do that.

If you replicate the sidebar on each page (which can be done with a simple load into a panel during B4XPage creation), the logic will be much simpler.
The B4XPageManager can do your work by showing different pages in response to the sidebar actions on the sidebar
that is on the page you're looking at.
 
Last edited:
Upvote 0

Blueforcer

Well-Known Member
Licensed User
Longtime User
I see. You can't dynamically load the layouts, since the underlying class instances need to operate continually, even when not visible.
That's why you need separate pages.

The problem (one you haven't mentioned) is that in B4Xpages you have to commit to a orientation at the start of the program.
That is one of the reasons B4Xpages doesn't pause. However, if you would be satisfied with this, you can set the orientation
early in the program (before initializing B4XPageManager) to whatever orientation the user is holding the device.)
If interested I can show you how to do that.

If you replicate the sidebar on each page (which can be done with a simple load into a panel during B4XPage creation), t
he logic will be much simpler.
The B4XPageManager can do your work by showing different pages in response to the sidebar actions on the sidebar
that is on the page you're looking at.

But the sidebar and the header will be created on each single page. That would eat much memory. Forthermore the usability is not that great as you can see on the disadvantages in Try2 in my first post. I already tried it and I'm not satisfied, especially with the huge work to parse the states from page to page. I only want to hold it once.
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
Of course this is try 2

Disadvantages
  • The intelligent views are running multiple times, but they shouldn't. wich could cause a much higher RAM usage as needed for some classes.
  • The B4XDrawer removes immediately when you call a new b4xpage. This doesnt look nice
  • You need to parse all current states of the sidebar to every b4xpage in order to keep the highlighted Item etc.`

I'll think some more about it.
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
Lets look at try1 again

Disadvantages
  • If i rotate the phone, it destroys all the views in the main activity, and need to setup again. This would destroy several classes( (for example some intelligent in the header) wich needs working in the background all the time, without too loose it for a short time. Also the Sidebar is destroyed and needs to build up again (this is not a layout, its generated from a json). Also all the color theming is gone and need to set again

In B4XPages and Android, since the orientation is committed, rotating the phone has no effect on anything (it stays in the same orientation).
This is an important fact. However, the following might be enough. It needs the Phone library.
(this is not needed in B4J and B4i)

B4X:
Sub Activity_Create(FirstTime As Boolean)
'    #SupportedOrientations: unspecified    <=== this is needed in #Region  Project Attributes

    Dim ph As Phone
    If Activity.width < Activity.Height Then ph.SetScreenOrientation(7) Else ph.SetScreenOrientation(6)
  
    Activity.Color = Colors.white
    Dim pm As B4XPagesManager
    pm.Initialize(Activity)
End Sub
 
Upvote 0

Blueforcer

Well-Known Member
Licensed User
Longtime User
Lets look at try1 again



In B4XPages and Android, since the orientation is committed, rotating the phone has no effect on anything. This is an important fact.
However, the following might be enough. It needs the Phone library.
(this is not needed in B4J and B4i)

B4X:
Sub Activity_Create(FirstTime As Boolean)
'    #SupportedOrientations: unspecified    <=== this is needed

    Dim ph As Phone
    If Activity.width < Activity.Height Then ph.SetScreenOrientation(7) Else ph.SetScreenOrientation(6)
 
    Activity.Color = Colors.white
    Dim pm As B4XPagesManager
    pm.Initialize(Activity)
End Sub

Maybe I misunderstood you


It's not about the orientation, it can be catched on any page with the resized event. That's the easiest part

And rotating the phone will recreate the activity.

My problem is not about changing the views orientation but the hold of the views and only one sidebar and header
 
Last edited:
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
Your problem is closely linked to view permanence and hence to B4XPages orientation.
You may catch/detect it on resize but you can't change it there, if you do the activity will pause and restart and your continuity of the activity is interrupted.

I am currently working on a project where I have a Class that manages other instances of other Classes.
If I don't pause the activity, those instances will run continuously.

One way to demonstrate this in a small project is to have a manager Class that manages 2 instances of a regular class.
Each instance has a label that shows a count up value. Instance 1 starts at 100 and instance 2 starts At 10000.
In the Class definition they are incremented once per second.
The manager (with a couple of buttons) can switch showing these instance and their labels and you'll see the appropriate count-up value.
 
Upvote 0

Blueforcer

Well-Known Member
Licensed User
Longtime User
Your problem is closely linked to view permanence and hence to B4XPages orientation.
You may catch/detect it on resize but you can't change it there, if you do the activity will pause and restart and your continuity of the activity is interrupted.

I am currently working on a project where I have a Class that manages other instances of other Classes.
If I don't pause the activity, those instances will run continuously.

One way to demonstrate this in a small project is to have a manager Class that manages 2 instances of a regular class.
Each instance has a label that shows a count up value. Instance 1 starts at 100 and instance 2 starts At 10000.
In the Class definition they are incremented once per second.
The manager (with a couple of buttons) can switch showing these instance and their labels and you'll see the appropriate count-up value.
Sounds like B4XPages :)
I will try to duplicate the B4XPages lib with a different name and use it inside the b4xMainPage from the first b4Xpage instance.
So it's fully Decoupled from the activity lifecycle
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
Not really. Here is very small demo of what I mean. (B4A).
 

Attachments

  • modelApp.zip
    14.9 KB · Views: 184
Last edited:
Upvote 0

Blueforcer

Well-Known Member
Licensed User
Longtime User
To lock the rotation after start is a great idea thanks for that

As mentioned i duplicate the B4XPage Lib.
The only difference is that this one does not need a B4XMainPage.

So far, my app is running with a B4XPageManager2 inside a B4XPageManager ?
Dont know if it will solve my problem or it was simply a bad idea xD , i will play more this evening. Keep you guys informend
 

Attachments

  • B4XPages2.b4xlib
    7 KB · Views: 146
Last edited:
Upvote 0
Top