This will be quick. I plan grand blog posts that never get written, but this one will be short, because my suggestion is simple, and if you have a sign up form in your app, this will get more users past it.
Sign up forms make me cringe. When I get to one, in almost all cases, they miss a chance to make things easy on the user. Sometimes many chances.
For example, today I downloaded Lift. Their rating average is 3.5, which means they failed. Its not a video recording app, or some crazy big data thing. Its a simple use case (yes, I know its harder than it looks, blah blah blah). Still, 3.5 is pretty much a fail with a simple utility app.
I don’t know much more about the app than the signup screen, because I opened it, typed in a bunch of info, got bounced around, then uninstalled it. I didn’t leave a review (unless you count this), but a lot of other people did. The sad part is its a simple signup form, and doesn’t have much data, yet short of crashing, they couldn’t have made it much worse.
This is the first screen. I’m pretty sure I signed up for Lift a while ago, but I don’t remember if I did. Problem #1. Most people don’t pay as much attention to your service as you’d like to think they do. Its hard to get around the signup/sign-in issue, but we’ll assume this is handled well later (spoiler, its not). I click “Sign up”.
- At the top it reminds me I can log in, but again, I don’t know if I’m a member. I wouldn’t say this is “solving” the issue.
- You can (probably) get name info from the device. If so, why do I need to type this in?
Repeat after me: All Clicks Hurt
yeah, capital letters are for chumps. who’s got time for that?
Its trivial to have the keyboard capitalize letters in Android. Absolutely no reason not to have that (there is here, but we’ll touch on that later).
Also, the button should be “Next”, not “Go”. I clicked it anyway after typing in my name.
Clicking Go apparently told the app that I wanted to submit, which triggered validation, which failed on fields I hadn’t entered yet. That’s frustrating. What’s worse is the pop up is pointing at nothing, but we’ll be assuming it’s pointing at the last name field. If your popups can’t reliably point at their target, make the field red. Or whatever.
I was going to skip this one, because its basically the same problem as above with the “Go” button, but there’s another issue here. From the error message, I assume the code is manually checking for a valid email. Its a very specific message. I assume the code is looking for the ‘@’. As a manager of developers that makes me think somebody put time in to code that, and hopefully they have a solid understanding of all the weird email format cases. All modern platforms have a way to easily check email formats, and I’m guessing the average user of Lift knows how to enter an email address, so specific error messages, other than “bad email, bro” (or similar) aren’t necessary.
In Android, do this:
The big issue with the email address field is why I started this post.
I HATE typing in my email. Its right there on the phone. Why am I typing that in?
A small percentage of users will want to know why you have the GET_ACCOUNTS permission, and of that percentage, very few will actually not install the app as a result. Many apps want your local account list, especially if you’re creating an account. I don’t have stats, but I bet far more users have uninstalled Lift due to the onboarding than would gripe about GET_ACCOUNTS.
I’ll get to it later, but I’m going to give you code to auto-complete the email address entry. It took me 10 minutes to write. Full stop. That was originally the sum total of this post, but then I really dug into what I didn’t like about Lift’s form, and here we are. Bug I digress.
Time zone? Its available on the device. You don’t even need permissions to get it. That’s all fail.
Clicked the button. Not-very-eye-catching error says “Email has already been taken”. By who? We’ll assume me, I guess.
This is the other huge problem with many sign up screens. Although maybe not great practice, I use the same password with most low-security services. Why? Because its easy, and I don’t care if somebody hacks my Lift account. Lift is not a bank. Hopefully you’ve got the passwords hashed on your backend, or somebody might be adding Smurfs 2 to my Netflix queue.
What’s my point? Even though I was on “sign up”, why couldn’t Lift simply check that info and log me in? To be fair to lift, few apps have figured this out, but it drives me nuts. You’ve got the info. Log me in. Don’t punish me because I didn’t remember that I’d signed up for your service 3 years ago.
We can lay off Lift a bit. They didn’t just get lazy here. The real problem? Lift is a web app. Its trying really hard not to make that clear, but it is, and no matter how pretty you try to make the screen, the little stuff is bound to be a little off. That’s why there’s a 3.5 rating (maybe not. I didn’t spend a lot of time on it). I’ll be honest. I usually notice the web apps right away, but didn’t with this one for a little while. And I run an Android dev shop. We can lay off Lift a bit, but users will not. They do not know or care about cross platform or high HTML5 ideals. Just throwing that out there.
Finally, the nail in the coffin…
I clicked the login link. Blank fields. I’ve already typed in BOTH on the other screen. You could at least carry the email over. I see that a lot, and its a total fail. You might as well uninstall the app for the user and save them time.
I’m being harsh, I know, but its a harsh world.
Even though this is a web app, its running inside some kind of native container, so you can get at the phone info. Pull email addresses from the local accounts, and offer them in a dropdown. I’m also pretty sure there’s a way to put custom html attributes to make the input smarter on the sign up screen.
For native coders, if you want to offer email addresses in autocomplete, here’s the code.
public class EmailAccountsEditText extends AutoCompleteTextView
public EmailAccountsEditText(Context context)
public EmailAccountsEditText(Context context, AttributeSet attrs)
public EmailAccountsEditText(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);
private void init()
new AsyncTask<Void, Void, List<String>>()
protected List<String> doInBackground(Void… params)
protected void onPostExecute(List<String> o)
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_dropdown_item_1line, o);
private List<String> findEmailAccounts()
List<String> emails = new ArrayList<String>();
AccountManager accountManager = AccountManager.get(getContext());
Account accounts = accountManager.getAccountsByType(“com.google”);
for (Account account : accounts)
private static boolean isValidEmail(CharSequence target)
return target != null && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
Add this to your screen, and make sure you include ‘android.permission.GET_ACCOUNTS’ permission. That’s it. You then get this.
Its that simple. I doubt you need the ‘isValidEmail’ check, but I threw it in just in case.
A little bit of code will save you losing some users. Listen to Yoda.
(Embedding didn’t work. Sad face. Why are video sites always broken somehow?)
PS. If you’re a Lift person and reading this, sorry. You just happened to catch me on post day, and kind of had all my big issues in one place. I did dig around looking for some html5 hacks you could use for caps and whatnot, but didn’t find them. So, anyway, sorry.
Went a little crazy this morning and coded a sample form.
You can find the code here: https://github.com/touchlab/LiftOneClick
Some points to note:
- We can get the display name, and I attempt to split it into first/last, but that’s generally bad. Were I coding this for real, I’d push to simply have a “name” field on the back end.
- I get the raw TimeZone list. Its huge. You’d need to put a little more effort into getting that and finding your default, but it wouldn’t be that bad.
On the plus side, this version is 4 clicks. 3 if I had checked first/last, and then focused on email automatically.
If you have 1 email address, the form is completely filled, and you only need to click once (the button).
Well, I’m not including password in the click count, of course. Should do oauth for that kind of thing.