Any fast way of creating images/buttons?

Hi all,

I am posting another question as the community here is great and I always get good answers.

First of all, I finally was able to finish my first serious application for class and, while I still have a lot of work with the visual design, the code is working and it it looks really cool thanks to Thunkable (and everyone helping here). There is one step that I am trying to optimize as it takes some seconds and it will also be helpful for my next app: a RPG game, so I would like to ask one question to the community.

I will try to explain my problem as best as possible: When I load a particular screen, this screen shows some buttons with the headings for a topic (for my class app) or the images with the components in an inventory (swords, potions, … for the RPG game).

Example: I click on “Lectures” and the application sends the user to a screen (Lectures) that will load 10 buttons:

  • Lesson 1
  • Lesson 2
  • Lesson 3
  • Lesson 4,
    …

My current app works with Anycomponent and it creates X Rows, each with a button in them and then writes the label “Lesson 1”, … in them… aside from some additional text alligned next to the button (% of completion).

Problem: When loading the “Lessons” screen it takes 1-2 seconds to show it, most likely due to creating 10 rows and 10 buttons and to make them visible…

Question: Is there any way that Thunkable will load this in memory (RAM) in a particular moment (for example, while I am in another screen) so that when clicking in the screen it does not take some seconds? or is there any other faster way to achieve my goal?

Note: I know that I can create X buttons in the design. I just wanted to avoid doing it due to two reasons: First, my current app works for several classes and not only one (it takes the data from Airtable and, depending on the numbers of Lessons, it creates X number of buttons). But even doing so, it would not solve my second issue which is related:

In my RPG game, I encounter the same problem: even if I have X slots (buttons or images) for the inventory, replacing the background image with the images (sword, potion, …) it takes the same amount of time. I cannot predefine the images as the inventory depends on which items the player gathers along the game. So the problem is the same: whenever I access to the inventory it takes 2 seconds or so to show everything because the app is trying to change all the images…

Is there any way of speeding up this process? It would be great if the loading part could be done while in the “Menu” screen where the user usually spends some seconds.

Thanks in advance.

Hi @neutronic_force7,

I opened a github issue #458 long time ago :slight_smile: where I said it could be useful to set some values in other screen. I thought it could not be that hard, because other things like app variables can also be set over screens. Since then I only got a “to be considered no ETA” by josmas. Hopefully your request brings some live back to this issue. I also would like to set values (or as you said create some any-blocks) in advance, before opening another screen.

Another idea would be to have real multitasking over screens, that means that every screen runs processes, even when it is not on display. That way you could set app variable X in screen1, and in screen2 you react to the event “when app X changes do…” even when screen2 is not visible.

Hi,

One of the problems with Thinkable X is the slow rendering of components. The developers managed to increase the speed of the block code, but this did not give the desired effect due to the very slow drawing of components.

You can try using the global function to create components on an inactive screen, which should speed up their display when the screen becomes active. The forum has links to an example with a global function and my demo project, where it is also used.

1 Like

Thanks for the replies.

Michael, hopefully they will implement something similar to what you suggest :slight_smile:

Actech, thanks. I have just realized that it was you the one that suggested to use the timer to call global functions. When I saw it two days ago, I used it to organize some of my code and it was very helpful, thanks a lot!!! regarding to the topic, could you please confirm that I understood it correctly?

Right now, I have the attached image in which everything is in the same “screen”: when this screen opens (PreguntasMenu) it will create different buttons based on which button the user pressed in the Menu screen (previous screen): if the user clicked on Lectures button (VengoDe=2) it creates buttons for each Lesson (Lesson 1, Lesson 2, …), if the users clicked on the Questions button (VengoDe=4) then it will create the buttons for the questions for each Lecture, and so on…

If I understood correctly, your suggestion is that I put the functions in my “loading screen”, make them global using the timer, and then call them in this screen (this step is already done). I don’t understand why should it be faster… wouldn’t it take the same time to read the function despite its location? or you mean that the fact that all this functions are in one screen makes it taking longer to load the screen?

Thanks in advance

The idea is as follows. The user opens the app
and while it sees the screen saver (which is useless in most cases)or any other screen, the any components are created in the background. However, this component creation should be done in a separate function, not in the Screen.Open block. If you create components in Screen Start or Open, there will be no gain.

The main problem is that the screen with the global function must exist by the time it is called. This means that you need to use the component with tab navigation.

I’ll try to show you my idea. Here you need a balance in that the background creation of components does not lead to freezing of the main flow of the application.

Everything is made much easier. See the basic example at the link below. In it, 100 buttons are created on the Screen 2 screen, but this does not freeze working with the app. You can’t say that Screen2 will be fully ready when the user switches to it, but It is created in parallel with the user’s work on other screens.

https://x.thunkable.com/projects/5dc53b8d5d8956e63f2765f6/project/properties/designer/

There are other ways, but unfortunately Canvas doesn’t allow you to implement them.

The timer block is triggered only on the parent screen when using navigation components. It’s sad.

Another way to speed up button output is to use a ListViewer instead.

Thanks a lot actech.

I am still confused. So “When Screen X Starts” will work in the background if that screen is inside Tab Navigation? and “When Screen X Opens” only when that screen is visualized, right?

I can see that the buttons are created in parallel as you said. That is great. The problem is that I don’t want any tab navigation shown and I cannot see how to hide it :sob: isn’t there any other workaround? what you suggest is exactly what I am looking for, but without tab navigation…

Also, how would it work if the content to be created is not the same over time? Let’s say that I fight a monster, I win and I receive an item. Is there a way so that, while the “Congratulations, you won X” is shown to the user and the used clicks “OK” which could take some seconds, to create the blocks in parallel in another screen with the new items? If I understood correctly, your solution won’t work in such case, right?

As I wrote, the global timer does not work when using the navigation component. For this reason, global functions will not work there.

On the other hand, to call a global function, it must be on a screen that has already been created. This requires either a visit to this screen or a Navigator component where global functions don’t work.

On the other hand, you need a dynamic screen where a large amount of data will be constantly updated. In this case, my solution will not wait, because it only works when creating a screen, as you correctly said. I may sound a little harsh, but if a driver wants to take part in a speed competition, then a race car is better suited for this, not an asphalt skating rink. I think you got the joke ))

But let’s get back to your question. From your question, I still don’t understand what you need. If you need to quickly create 10 buttons, then I don’t see any problems here.

If you want to create a game, you need to use a high-performance canvas, and this is a completely different question. It turns out that you have confused us and yourself a little. 10 buttons and the game assume completely opposite performance requirements.

How can I quickly create 100 images? See information about the sprite map, which speeds up the loading of a large number of images. However, the current version of Thunlkable X does not support the sprite map.

What would I do in your place to create a high-speed canvas? I used the WebViewer component and some physics framework to create games. But then you will get a web application that will not be accepted in the Apple Store.

Thanks a lot actech and sorry for the confusion and for so many questions,

Your solution is smart and elegant but it won’t work without Tab Navigation.The problem is that I need to create 10 buttons, but I don’t want to use the Tab Navigation because I did not see how to hide the tabs (which I really don’t want).

The second example of the game was not about the game itself (it will be a simple game so current canvas is more than enough) but to the inventory. Let’s say that a button sends the user to “see” the items in the inventory. This “inventory” screen has 10 slots (buttons or images). Whenever I pick up an item in the game it would be nice to have the application switching the background images of the “inventory” screen before I go into that inventory screen, so that when the user goes to that screen it won’t take some seconds to show the inventory. (EDIT: just to make it clearer, the “inventory” screen is a new and simple screen outside the screen with the canvas).

So the performance requirements should be similar because, instead of creating buttons, in this case it will be replacing the background images in the “inventory” screen, which also will take a similar amount of time. But, in any case, the problem is still the same: I am forced to use Tab Navigator which I do not want. It would force me to redesign all the layouts that I have in mind making it less apealing (in my opinion).

Hi actech again,

I will never get tired of thanking you. I was playing with your solution using some tests and I was able to get what I wanted using Tab Navigator, so your solution is perfect for using tab navigation, you are a genius.

Now I will try to see if I can find a workaround without tab navigator or, at least, if there is any way of removing the tabs from the layout…

Thank you for your explanation. Now I understand the situation about the buttons and the game. Unfortunately, the fastest way is to manually create all the buttons and images, and then change the labels and images on them.

Unfortunately, you can’t get rid of tabs in any way, even if you disable labels and icons. If I find any other solution, I will share it.

1 Like

Thanks actech,

I think I found a solution thanks to your help. I made the following test application (I attach the link to the proyect below) while trying to maintain the logic in my real app (loading screen, navigation screens, …):

https://x.thunkable.com/projects/5f4918df177aa5bfc31a4760/5022b5c3-bf67-4cfa-9f51-e132016687be/designer

1 - I made a loading screen to load all the variables, common functions, …
2 - After finishing with the loading then it should have navigated to screen 1, where the user will have the main menu. But the first time I navigated to the “slow” screen it was not working as expected. As you said before, it first needs to navigate to the “slow” screen where the components will be created, so to load the function. Therefore, instead of navigating inmediatelly to screen 1, I made the app to move to screen 3 after the loading. I made a condition: if it is the first time the app is loaded then it just does nothing (well, it trully runs thought the screen and only loads the funcitons). So it inmediatelly moves to Screen 1.
3 - Afterwards, I can make Screen3 create stuff in the background (in this case, whenever I navigate to screen 1 it loads Alert1 which created the components in Screen 3.

I understand that the explanation is quite bad… Probably you will understand better by looking the project. By the way, the stuff for temp1, temp2 and screen 2 was a test because I wanted to know the difference between Screen Start/Open when inside a navigator tab and when outside, so you can skip that part. The idea is just that Screen 3 loads the buttons in parallel whenever something happens (in this case, whenever the user goes to Screen 1).

I realized that only the screen to be updated in the background (in parallel) needs to be in the Tab Navigator. The rest can be outside. Finally, I spent one hour trying to hide the labels from the navigator tab, which can be done, but it leaves a spacing in the top which cannot be filled and looks horrible. I also did not find a way to change the text, … but finally I saw the light: while Top Tab Navigation does not allow to hide the tabs, Botton Tab Navigation does!!! :slight_smile: That is why everything is aligned to the botton of the screen, to test that the tab actually does not require any spacing.

I will try to implement this in my app to test it but it looks perfect now.

One last question. Do you have the experience about the “Interval” in the timer for those cases where you only “enable/disable” them inmediatelly as in this test project? I am afraid that if I set them to 0 miliseconds so that the function inside the timer runs as soon as possible, the app will run crazy… I will check it, but maybe you have some experience using it.

Thanks once again :slight_smile: