Dmytro Danylyk
Timee GmbH.
"Screens Planing - is a process of preparing app flow, screens logic, layout & design - before programmer writes the first lines of code."
"Designer should not be the sole decision-maker".
"Be sure your lead developer/architect is involved very early in the screen planning process".
"Developer will be able to give your design team visibility into areas of the design that can either become costly to implement, or present performance challenges for the app."
"To prevent development surprises and cost overruns during the project".
Answers question: "Is this screen necessary?"
Answers question: "How other applications solve similar problems?"
Answers question: "What is this screen responsible for?"
Answers question: "How this screen will look like?"
Draw simple relationships diagram.
Download few applications which have Sign In screen and check how they solve problems like:
Internet is not available
Input data is not valid
Loading indicator
...
Vine application
Vine application checks if network is available, after the user clicks on the Sign In button.
Airbnb application tracks when text inside login and password input fields changes.
Log In button stays disabled until input data is valid.
Airbnb application
Keep application validates data after user clicks on Done button.
Keep application
Swarm application disables login, password and sign in widgets, and replaces sign in button text with loading indicator.
Swarm application
Swarm application disables login, password and sign in widgets, and replaces sign in button text with loading indicator.
Swarm application
Vine application displays standard progress dialoge.
Vine application
Duolingo application disables login, password and sign in widgets without displaying any loading indicator.
Duolingo application
Duolingo application disables login, password and sign in widgets without displaying any loading indicator.
Duolingo application
Pinterest application pre-fills email field so we don't have to type it manually.
Pineterst application
Airbnb application greatly improves user experience because allows to Sign In with a simple tap.
Airbnb application
By default when user presses keyboard Done button – it closes keyboard.
Tumblr application handles this click and performs Sign In request.
Tumblr application
Perform Sign In
Handle network state
Handle data validation
Display loading indicator
Pre-fill data
Social Sign In
Write down a list of Sign In screen features.
Write down few suggestions regarding Sign In screen design.
Do not place important functional buttons at the bottom of your screen.
At least make sure they are moved to top when keyboard is displayed.
Tumblr Android
Do not place important functional buttons at the bottom of your screen.
At least make sure they are moved to top when keyboard is displayed.
Tumblr Android
Do not force users to make unnecessary clicks, show keyboard automatically.
Remember the 3 clicks rule: with every three clicks you lose 50% of your audience’s attention.
Pinterest application
Make sure keyboard doesn't overlap your Sign In button or any other top componenets.
At least make your container scrollable.
Foursquare application
public boolean isEmailValid() {
return Patterns.EMAIL_ADDRESS.matcher(getEmail()).matches();
}
public String getEmail() {
return mEditEmail.getText().toString().trim(); // mEditEmail
}
To validate email you can use Patterns.EMAIL_ADDRESS
1.
String phoneNumber = "044 668 18 00" // Switzerland phone number
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
PhoneNumber phoneNumberProto =
phoneUtil.parse(phoneNumber, "CH"); // CH - Switzerland country code
boolean isValid =
phoneUtil.isValidNumber(phoneNumberProto); // returns true
// Produces "+41 44 668 18 00"
phoneUtil.format(phoneNumberProto, PhoneNumberFormat.INTERNATIONAL
// Produces "044 668 18 00"
phoneUtil.format(phoneNumberProto, PhoneNumberFormat.NATIONAL
// Produces "+41446681800"
phoneUtil.format(phoneNumberProto, PhoneNumberFormat.E164)
To validate/format phone number you can use google libphonenumber
2.
Pattern emailPattern = Patterns.EMAIL_ADDRESS;
Account[] accounts = AccountManager.get(context).getAccounts();
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
String possibleEmail = account.name;
}
}
To pre-fill user data you can use AccountManager
3.
Don't forget to set EditText attributes
4.
Handle keyboard done button
5.
mEditPassword.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
boolean isValidKey = event != null
&& event.getKeyCode() == KeyEvent.KEYCODE_ENTER;
boolean isValidAction = actionId == EditorInfo.IME_ACTION_DONE;
if (isValidKey || isValidAction) {
// do login request
}
return false;
}
});
Note: some keyboards support changing keyboard action button text android:imeActionLabel="SignIn".
Provide meaningful error messages
6.
if(!isEmailValid()) {
showToast("Please enter valid username.");
} else if(isPasswordEmpty()) {
showToast("Please enter password.");
} else if(!isNetworkOn()) {
showToast("You don't have internet connection.");
} else {
doSignIn();
}
Note: error message should answer a question "What is wrong?" and in some cases give user a hint how to fix it.
When you try to Sign In to Airbnb application without internet connection it displays error dialog with advice "Please try again".
Airbnb application
Trying to use Social Sign In inside Airbnb application without internet connection, ends with obscure error message and infinity loading dialogue.
Airbnb application
Provide cancellation mechanism
7.
class SignInRequest extends AsyncTask {
// implementation omitted
}
SignInRequest mSignInRequest;
void showLoadingDialog() {
...
alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
// guarantees that onPostExecute() is never invoked
mSignInRequest.cancel(false);
}
});
alertDialog.show();
}
Vine application
Vine application
Vine application
Vine application
Vine application doesn't ignore http request callback when dialog is dismissed.
As a result Toast with error message appears after loading dialog was dismissed.
Tumblr application
Tumblr application
Tumblr application
Tumblr application
Tumblr application
Tumblr application doesn't ignore http request callback when user switch from Log In to Sign Up.
As a result error labels appears in wrong state.
Use AccountManage and SyncAdapter
8.
Sign In screen is not always MAIN
9.
<activity android:name=".SignInActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
When you have a sign in screen in your application it doesn’t mean it should be your main launcher screen.
Typical flow
Issues
Sign In activity
if(isAccessTokenValid()) {
startHomeActivity();
finish();
} else {
initViews();
}
Better flow
Home activity
if(isAccessTokenValid()) {
initViews();
} else {
startSignInActivity();
finish();
}
"You can get an application into production without animations, but these little things can be the difference between your app receiving 4 star or 5 star reviews."
"Animations which help to provide context are called - functional. They help brains understand how the information flows".
Click to remove item without animation
Click to remove item without animation
Click to remove item with animation
Click to remove item with animation
"Animations which make usage of your app more interesting and fun are called - "delightful & cute". They bring uniqueness to your application and help user to remember you."
Delightful pull-to-refresh weather animation
"Flow and design changes very often during development iteration. That's why development of complex, time-consuming animations is usually postponed to the very end, when core application development is completed."
"Animation prototyping is a way to quickly mock up animation without having to write any code."
"Because you can see order of transformations applied in prototype and convert them into code."
Pixate creates 100% native app prototypes that run directly on your iOS or Android device. The process works like this:
In order to see and interact with what you're creating, you'll need to connect your device to Pixate Studio.
Detailed tutorial is available on official Pixate knowledgebase.
The layer list is home to all of the layers in your prototype.
The second tab is where you upload images to use in your Prototype.
Actions are scripts that can be run to complete common tasks, like setting up a scrollview or aligning a layer.
Interactions are gestures and actions users will perform in your app.
Animations move, scale and change layers, depending on the interaction performed by the user and the properties you set up
The canvas is the visual representation of your prototype. What you see here, is what you will see in the preview.
This is where you can adjust the layer’s position, size or orientation with values and change the appearance of the layer.
These are used to define the conditions, ranges of an animation and interaction relationships.
After user tap on picture, details view slides from left.
'picture'
'detail view'
1. Cut necessary resources and add them to Pixate Studio assets.
2. Drag & drop asset images to canvas and create layers.
3. Move 'detail view' to initial position (off the screen).
4. Select 'picture' and click on 'Tap' interaction.
5. Select 'detail view' and click on 'Move' animation.
The layer the animation will be based on.
Read as: when someone taps on 'picture'.
Layer moves with duration, once a set condition is met.
These options tell the layer where to move to.
Easing curve you want to use for the animation (optional).
Read as: when someone taps on 'picture' move this layer '90pt left' with 'spring' easing curve.
int tension = 300;
AnticipateOvershootInterpolator interpolator
= new AnticipateOvershootInterpolator(tension);
detailView.animate()
.yBy(-90) // left 90 pt
.setDuration(2500) // friction 2.5 sec
.setInterpolator(interpolator)
.start();
After user tap on picture, details view slides from left.