Home » Posts tagged 'template'
Tag Archives: template
This is an extension of the tutorial A login template for App Inventor published some months ago. The goal of this new version is to incorporate some wonderful ideas I’ve received since then:
- A more professional look for buttons (Erikv)
- Change resizing algorythm (Erikv)
- Direct login (Erikv)
- Fusiontable storage (Richard Lafleur)
- Multilingual (my own suggestion)
- Hyperlink from the help screen (also mine)
- Migration to Python 2.7 (Alvin , Orlando… and Google!)
Thanks for your ideas. Please keep commenting and I’ll do my best to enhance the template based on everybody’s contribution.
About this tutorial
The explanations in this post are not as extensive as they were in first part. We’ll see the goal of each new functionality and how it’s been solved, but without diving into technical details except to remark any tricky aspects.
The sources for App Inventor can be downloaded here. As usual it’s enough to upload the zip file into App Inventor and the app should work directly except for the following limitations:
- The database is stored in the default appinventor.appspot.com service which is not a good practice.
- The “Forgot password” screen won’t be able to send mails until you set up a service as explained in the tutorial How to send direct emails with App Inventor.
- The “Google login” will not work until you define the right values to the variables CLIENT_ID and CLIENT_SECRET as explained in the tutorial How to identify your user with OAuth from Pura Vida Apps.
In order to overcome the first two limitations, you can set up the AppEngine service available in the above mentioned tutorial How to send direct emails with App Inventor.
How it works
As ErikV says “default buttons in AI look childish”. The most immediate way to achieve a more professional effect is using icons. There are some good examples on the web, but I was worried about author rights and I’m not good at photoshop. Erikkv proposed this wonderful site but I was not able to produce icons that looked nice in AI buttons so I ended up with some home-made stuff. They’re definitely far from ideal but at least they enhance the previous version. If someone can contribute with a better option I’ll publish them in version 3!
The template is currently available in English and French (sorry for my limitations in both languages). The user can choose the language clicking on the top-left flags and all texts are automatically changed:
The mechanism for supporting several languages is explained in the post A multilingual & multidevice template for AppInventor. To avoid confusion with the previous code, I’ve placed the new blocks in the lower part:
As explained in the above mentioned tutorial this code needn’t be modified except for the InitConstants function where you can adapt the texts for each concrete app. Just changing the two lists listItems and LST_DEFAULT_TEXTS you should be able to modify translations, add a new language, add new texts, etc.
Erikv suggested changing the arrangements and size with the orientation, but without reshaping them. I’ve had a thought about it taking also into account my recent experience and I’ve decided it’s not realistic to define a standard behavior, because it will depend on each app, the kind of controls used, the number of devices we intend to support, etc.
So the template is currently configurable as explained in the same post A multilingual & multidevice template for AppInventor. By default, the current behavior is the same as in the previous version, i.e. only height and size of menu options are resized according to screen size and orientation. However as I say this is easily configurable. For example, if we prefer the height to be fixed we just need to leave blank the 7 constants (4 buttons + 3 spacer labels) as shown in next picture:
Erikv proposes enhancing the user experience by starting with the menu, and only prompt for a login when the user intends to use certain features. To do that, I’ve added some buttons on the top right bar, which change according to the current state: if the user is logged it’s possible to logout or change profile information, and otherwise there’s only the option of logging in:
The implementation of this behavior has consisted of some simple changes because the infrastructure was already set. It has mostly affected to the ShowScreen function which takes care of enabling or disabling the top bar buttons:
TinyWebDb is simple to use from AppInventor but managing the data from the server is not very user-friendly. In our case, it would be useful to have a list of users that could be ordered, filtered by a given attribute, etc. This is typically achieved with datasheets, so Richard proposed to store users in a fusiontable. I considered two possible approaches for the implementation:
- Server side: Modify the service in order to redirect TinyWeDb calls to a fusiontable.
- Client side: Modify the code blocks in order to use a Fusiontable component rather than a TinyWebDb
I was initially inclined towards the second option because it looked smarter, but then I realized that modifying the client is an irreversible action involving some extra requirements for the template (creating a fusiontable, managing security…). From this point of view, the first option is more flexible because the same client app can work both with Fusiontables and TinyWebDb (it depends on which service you set up). So finally I’ve decided not to modify the AppInventor but rather to set up a service that redirects to a fusiontable any tag request starting by “usr:”. To install it you need to download this main.py and replace the one you have set up for the app. Then you’ll have to modify the SETTINGS section as explained in the comments and deploy the service from AppEngine.
This solution may appear somewhat artificial but it’s practical, and it has given me the idea for a future service that extends the approach of combining the ease of use of TinyWebDB with the server side possibilities of fusiontables. Anyway, if anyone is interested in modifying the client side, it’s just a matter of including a Fusiontables component and making the following changes to the code blocks:
- Fusiontable.DoQuery instead of TinyWebDB.GetValue
- Fustiontable.GotResult instead of TinyWebDB.GotValue (and a slight adaptation to parse the result)
- Fusiontable.DoQuery with an INSERT statement instead of TinyWebDB.StoreValue
Hyperlink from help
This is just a small enhancement I had in mind. The previous template provided the skeleton of the help screens with plain text. The new version includes a hyperlink in the last line that when pressed opens the web indicated in the text:
The solution is quite simple: the text is actually a transparent button and when clicked it calls the associated URL using a Web component.
Python 2.7 migration
This suggestion came both from Alvin and Orlando, but I should rather say it was actually imposed by Google when they announced Python 2.5 is not going to be supported anymore starting from January 2014. This affects only the mail sending functionality so I’ve simply updated the mail post and included the migrated sources. If you’re interested in the steps required for the migration you can have a look at the post Python 2.7 migration demystified.
This post shows how to create a login system using App Inventor. The objective of the post is twofold: on the one side to provide the sources of a working template that can be reused in further applications, and on the other side to explain the fundamentals of its development.
You may be interested in this template if you intend to develop an app that requires the user to identify himself. This is useful for example in a game where you want to record the results and provide a classification of best scorers, or in general whenever you intend to enhance the user experience by tracking its history and remembering some of its decisions about configuration, look&feel, etc. Moreover, user identification is a great way to create a community around your apps. I’d rather say it’s a must.
On the other hand, user identification has some drawbacks. For example it can imply an entry barrier to your app, as some spontaneous users will be reluctant to identify themselves and hence renounce to log in. This is not a concern for me because I prefer having a small set of really interested users than lots of downloaders who uninstall the app after their first trial. Anyway, the template provides a “login as guest” functionality that allows users to have a look at the app before registering.
When I realized I needed to provide user identification for some of my AppInventor apps I started looking for a solution on the web. There are several posts related and some ideas for a solution (the closest one this server side solution), but none of them matched completely with what I had in mind, so I decided to develop the functionality on my own, assembling parts from those clever ideas into a cohesive module supporting all my requirements. The job was slower than expected, but I’m satisfied with the results and I’m sure it will save me a lot of work from now on because it can be reused as a template for any future app. In particular, I’ve recently publisehd an app to Google Play that uses the template we’re going to see.
01/08/2013: There’s a new version of the template available in this post. If you’re just interested in the sources you can go there directly, but otherwise I recommend you to have a previous look at the remainder of this tutorial because it has more extensive explanations about the template goals and behaviour.
26/07/2014: New sources for AppInventor 2. Indeed the post was initially published for AppInventor classic, but currently sources are available for both versions. The tutorial is also updated, but only with minor changes since the app is roughly the same.
About this tutorial
The format of this post is somewhat different from the two kinds of the tutorials most frequently found on the web:
- Step by step: very detailed instructions that fully guide you to develop the application. For a matter of space, they use to be basic and avoid some aspects (e.g. user entry verification) which are not necessary for a prototype but need to be taken into account for real applications. Good examples of this kind are the official AI tutorials.
- Tips and tricks: ideas to solve specific problems. There is usually the full code and some explanations, but also for a matter of space they don’t use to be full applications. A good example of this kind are Puravida snippets.
So both kinds of tutorials fail to cover the nuts and bolts for passing from a prototype to a production application. This tutorial will try to do so, since as I said we’re creating a template that I intend to reuse in all my apps with as little adaptations as possible. This broader scope comes at the cost of less detailed explanations, but my goal is to provide enough information for an intermediate reader to understand the module and be able to build or adapt it on his own. However sometimes it’s difficult to find the right balance so if anyone is interested in any further detail please leave a comment or contact me and I’ll be pleased to answer. Also remember that any detail omitted in the explanation can be discovered by inspecting the sources.
Therefore my recommendation is not to try to develop the full application from scratch, but rather download the sources and try them to see the app working. Then read through the tutorial and use the sources to review some details that may not be clear.
What are we going to build
The main functionalities provided by the template are:
- Login dialog: The entry point to the application. Requests the user to identify himself if he’s already registered and allows new users to register. It optionally remembers the previous username/password thus allowing users to log in with a simple click.
- Register: The user provides at least a username and password, as well as some additional information (that can be customized for each application). This information is stored in a database, with password encrypted.
- Forgot password: If the user had provided an email, the password is sent to the address. Otherwise it’s shown on the screen.
- Google login: The user can identify himself using his Google account. This way he needn’t remember yet another password. In this case, the user is also created in our database in order to store the information specific from our app, but we don’t record its password and email.
- Profile screen: Allows user to change his register information once within the app.
- Initial menu: The skeleton for the initial screen integrated with the login dialog.
|Initial screen||Register||Forgot password|
|Google account login||Menu||Help|
Choose one of the following versions:
|1.0 (AI Classic): This is the version explained in this post||Download|
|2.0 (AI Classic): This version contains some enhancements explained in this post||Download|
|3.0 (AI2): This version has the same functionalities as v2.0. It’s just an adaptation for AI2||Download|
How to install the app
Download any of the versions above and upload it as a new project into AppInventor. This should work directly except for the following limitations:
- The “Forgot password” screen won’t be able to send mails (it will show the password as a message). For this to be possible you need to enable a service as explained in the tutorial How to send a direct mail.
- The “Google login” will not work until you set the variables CLIENT_ID and CLIENT_SECRET with the values that the API Console has given to your application, as explained in the tutorial How to identify your user with OAuth from Pura Vida Apps.
- The database is stored in the default appinventor.appspot.com service which is not a good practice. Please consider enabling a specific service as explained in the tutorial Creating a Custom TinyWebDB Service.
How it works
In order to keep this post to a reasonable extension I’ve moved some contents to separate posts. Concretely the solution to some specific challenges I faced when developing the module and that were not trivial to solve (at least for me):
- How to send a direct mail
- An “optimal” way to manage multiple screens
- How to redirect to the Google login (from Pura Vida Apps). NOTE: This snippet is no longer available and has been replaced by an AppInventor Extension. I haven’t updated the template to this extension yet. So currently the Google redirection is still working but you cannot find an explanation in this blog
- A simple way to encrypt and decrypt texts in App Inventor
- How to adapt to screen orientation
Also for extension sake, all the coding stuff is explained separately in the second part of this post
Notice there are only two screens even though the template consists of seven windows. The reason is that six of these windows are implemented as table arrangements in the first screen (see the red square in the Components tree-view) which are hidden/shown by code in order to simulate the windows transitions. The reasons for using this mechanism rather than the multiscreen facility now available in AI are explained in the tutorial An “optimal” way to manage multiple screens.
The following chapters are devoted to each of the seven arrangements, and a final chapter covers the remaining components of the app.
This is the window displayed initially and the most complex one. It contains several arrangements which provide the desired layout for the following components:
- TextboxUser, TextboxPwd: Contain the username and password to be filled by the user
- ButtonLogin: Opens the menu after validating the username and password indicated
- CheckboxRemember: Indicates whether the data entered in the screen is recorded for next time (using Tinydb)
- ButtonRegister: Opens a new window (TableArrangementRegister) allowing user registration
- ButtonForgotPwd: Opens a new window (TableArrangementSendPwd) where the password will be reminded interactively or by email
- ButtonGoogle: Opens a new window (TableArrangementGoogle) that shows Google’s interface for login
- ButtonGuest: Opens the menu without validation
This is the application menu, which is accessed upon successful login. The template contains 4 generic options but it can obviously be adapted for each app.
The components are very simple. No secrets with buttons: one for each option and an additional one for “Exit”. Labels are somewhat trickier because they’re used to leave some space between buttons. The TableArrangementMenu1 has 4 columns and 5 rows and the labels are positioned in:
- Label1_3: Row 1, Column 3
- Label_3_1: Row 3, Column 1
- Label_5_3: Row 5, Column 3
To achieve the layout required, you can specify the desired height and width for these labels. However, these attributes will be overridden by code (see the Screen Orientation tutorial).
This is the window where the user registers into the app. After introducing its identification data and pressing the Ok button a new record is stored in the database (validating previously that the username does not already exist).
- LabelName_REG, LabelPassword_REG, LabelPassword2_REG, LabelMail_REG: Identifying labels. The prefix “*” indicates mandatory fields (this will be validated by code)
- TextboxName_REG, Password_REG, Password2_REG, TextboxMail_REG: The fields where the user enters his information
- CheckBoxSendMail_REG: Indicator of whether the user will receive email notifications
- ButtonOk_REG: Stores data and closes the screen
This window notifies about the password stored for a given username. If user’s email is informed the notification is sent to that address. Otherwise it’s shown as a screen message.
- LabelName_SEND, TextboxName_SEND, ButtonOK_SEND: No secrets
- LabelSep1_SEND: Spacer label to leave some space at the top. Inform the required height
- HiddenMail_SEND, HiddenPassword_SEND: These are auxiliary fields used to store the mail and password retrieved. They MUST NOT be shown in the screen, so mark the “Visibility” attribute as Hidden
This is the window that shows the Google login interface. All the magic is performed by code, so it has simply two components:
- TableArrangementGoogle: Used to achieve a full screen layout. Inform Height and Width to Fill parent
- WebViewer1: The component used to show Google’s web interface. Inform Height and Width to Fill parent
This is the window that appears when the user presses the “Help button”. We reuse the same interface for all windows despite each one has a specific text help. This is achieved by code (i.e. the right text is loaded according to the window from which the help is invoked).
Therefore the window has a general structure consisting of a header (VerticalArrangement3), a body (VerticalArrangement2) and a footer (LabelLogo). After creating these arrangements we can simply drag into them the appropriate labels. In our case:
- LabelHead: The title. Mark the Bold attribute and inform a slightly bigger text size (e.g. 16).
- LabelHeadSpacer: Just a spacer. Leave the text blank and inform a small height (e.g. 10)
- LabelHelp1, LabelHelp2, LabelHelp3, LabelHelp4: The labels that will contain the help body. Place one above the other in the VerticalArrangement2 and inform their width as Fill parent.
- LabelHelpLink: A text that can show a web address as the last line of the text help. Inform the attribute TextColor = blue.
- LabelLogo: A logo to be shown in the footer. You’ll probably prefer to use an image rather than a label. In this case you’ll probably require a HorizontalArrangement to center the image
Finally here are the non-visual components
Finally here is the template’s second screen, i.e. the one that will be opened when user presses any menu option. If you use this template in a real app, this is the screen that will necessarily have to be adapted.
At the level of this template we simply include the header bar (which shows the logged user), a generic help window and a label (which shows the selected option). Both the header bar and the help window have the same interface we’ve already seen for Screen1 so we’re not going to explain them again.
And that’s all regarding the graphical interface. The app is designed and now it’s time to program its behaviour. This will be explained in part 2.