/Android-Style-Guide

Style guide for Android by Xmartlabs

Creative Commons Zero v1.0 UniversalCC0-1.0

Xmartlabs' Android Style Guide

This is the Xmartlabs' Android and Java Styles Guide. These are conventions in general followed by the team.

To set it up, download the Android Studio style file and copy it to config/codestyles in your Android Studio settings folder. For Mac OS you should copy and paste the same file to Users/me/Library/Preferences/AndroidStudio1.5/codestyles. Check that the folder is the correct Android Studio version, and if necessary, create the codestyles folder.

Then in Android Studio, in Settings/Code select it. Note that this configuration enforce most of the points found in this guide, but not all.

You can reformat the code automatically by pressing Ctrl + Alt + L (default keyboard shortcut for Reformat Code). Is also recommended to commit with git via Android Studio and that Reformat Code is enabled when doing this.

Java

The idea is to follow Google Java Style, but with some changes and adding ideas.

Changes

Column limit

We use 120 as the column limit. Not 80, nor 100.

Vertical whitespace

There must be no vertical whitespace before the first member and after the last one of a class.

public class ClassExample {
  private int firstMember; // no vertical whitespace before this line

  // ...

  public void lastMember() {
    // ...
  } // no vertical whitespace after this line
}

Multiple vertical whitespaces must never be used.

Empty blocks

Empty blocks are preferently closed immediately after it is opened, with no characters or line break in between, unless it is part of a multi-block statement (one that directly contains multiple blocks: if/else or try/catch/finally).

Google Empty block preferences

Array initializers

The preferred array initializer "block-like construct" style when it doesn't fit in one line is one value per line:

new int[] {
  0,
  1,
  2,
  3,
}

Numeric literals

float-valued literals use a lowercase f suffix: 100.23f.

Class and interface names

If it's a list of an entity, use singular: CustomerListFragment for instance.

Field, method, variable and parameter names

If you need to name a List of activities for example, just name it activities and if it's ListView: activitiesListView. So we use plural here.

Local variable names

One-character names are only permitted if they are i, j or k indexes in loops. They must be used in this respective order when nesting them. Avoid using these loops indexes outside of them too. Example:

for (int i = 0; i < n1; i++) {
  for (int j = 0; j < n2; j++) {
    for (int k = 0; k < n3; k++) {
      // ...
    }
  }
}

Type variable names

A single capital letter must be used, such as T, S or D.

Where Javadoc is used

Javadoc must be taken into account only in projects that are an API, open source or if it's explicitly requested. It can also be used in places that looks necessary in order to clarify certain behavior.

Additions

Conditional operator

The conditional (ternary) operator may be used if the conditions and its corresponding values are considered to be simple enough. The readability of the code must not be disturbed. Also, it must not be used nested. If it doesn't fit in one line, it could be up to 3 lines, being one line for the condition, one for the first value and one for the second one. But if it doesn't fit in 3 lines in this format, it shouldn't be used. Example:

// This is okay:
boolean minValue = value1 < value2 ? value1 : value2;

// This is okay:
int someValue = value1 < value2 && value1 < value3 && value1 < value4 && value1 < value5 && value1 < value6
    ? value1 + value2 + value3 + value4
    : value2 + value3 + value4 + value5;

// This isn't okay:
String userHasProperty = user != null && Objects.equals(user.getProperty(), "a sample value")
    ? String.valueOf("%s %s %s", "Some", "very very very very very very very very very complicated",
    "and very very very very long string")
    : (user != null && user.satisfiesCondition() ? "this string" : "this other string");

Ask for the positive

Following Martin Fowler's Remove Double Negative refactoring, try to make the conditionals single positive.

Interfaces naming

Interfaces names must not have an I prefixed, like in IComparable (just Comparable is preferred). In the particular case of having an interface and an abstract class that implements it giving a default behavior, prefix the class with the word Abstract. Examples of this can be found in the Java API: Queue and AbstractQueue, Set and AbstractSet, among others.

Increment and decrement operators

Inline use of increment and decrement operators should be avoided. The outcome of the calculation is less easily predictable. Example:

// This is fine:
int aValue = otherValue * someValue + 1;
someValue++

// This does not:
int aValue = otherValue * someValue++ + 1;

Inner classes and interfaces

Only use them when they refer to something private to the class (only the class will use it) and they are small in the number of lines. Also when there is no other choice than they are non-static and when it's an interface related to a callback (like OnClickListener inside of View).

Nullable and NonNull

Try to use wherever you can the @Nullable and @NonNull annotations from the Support Annotations. Besides doing this messes up the code, it helps to avoid NullPointerException with the help of Android Studio's lint.

Usage of TODO and FIXME

Where possible, use TODO and FIXME comments. Write a date when using them. When using IntelliJ IDEA and Android Studio, you just press "todo" or "fixme" and it lets you autocomplete with a message. Use TODO when you are leaving something to be done that you are not going to do now and FIXME for something similar but related to a bug.

Android

Alphabetic order where possible

Always you have something that order is the same from the machine perspective, prefer to sort it alphabetically. An example of this the methods order in a builder construction, or the enum values order, if the enum value ordinal doesn't care and if the order doesn't go along with some logical order.

Fragments and Activities classes naming

These classes must be named after the use case they satisfy, suffixed by Fragment or Activity. Examples are: CustomerListFragment and RepoDetailActivity. Fragments that are used only as pages in ViewPagers, as if they were "weak entities" (they shouldn't exist outside it) must be called with the suffix PageFragment, such as in TutorialStep1PageFragment.

Class fields order

Fields go first. They are logically grouped in this order: constants, Activities extras, Fragments arguments, views, dependency-injected members and then plain fields. Additional subgroups can be defined.

Resources

We follow the Resources section of the Futurice's Android best practices, with the following adjustments.

Layouts

Regarding the naming we use underscores instead of dots. Also, we add that list item views follow the convention of prefixing with item, as in item_customer.xml. If naming a list header (header item or header of the whole list), use the prefix header.

Attributes with a namespace come first. Between those, first id (if present), then layout_width and then layout_height. Then the rest alphabetically. After this, the ones without namespace, such as style, alphabetically.

Namespaces declarations shall be the first lines in the root element and must be ordered alphabetically. The name for http://schemas.android.com/apk/res/android must be android, http://schemas.android.com/apk/res-auto must be app and the name for http://schemas.android.com/tools must be tools.

A single vertical whitespace must be left before a closing tag.

The naming of the ids of the views is the following. First, if it applies, try to use Android provided ids. This applies mainly for ListViews, RecyclerView, lists items TextViews and so on. If it doesn't apply, the name must be the context associated, then the name and finally the view name. All snake cased, except for the view name. Example: customer_list_description_textView. If a layout needs identification, it's better to suffix it with just layout, as normally relativeLayout or similar won't contribute much. Also, if naming a place where a fragment will be added, name it or suffix it with fragment_container.

Styles

The style files should be split in different files if the size of the project is big and it deserves it. Also, use styles in views only if they are reused.

The naming should be prefixed with the view name followed by a dot. Logical organization of different names (as namespaces) should be separated with dots too.

Colors

The color palette shouldn't have many elements. So it's okay for color names to be red, orange and so on (intituively inferred). If having repeated colors, use versions like redLight, redLighter, redDark and redDarker. There shouldn't be much more (it might reflect a design problem). For alpha versions of other colors, prefer the convention red20 (being 20 the percentage of opacity, in decimal). For transparent tinted versions, use something like transparentBlackRed.

Strings

Split the strings with dots based on words that give context. For example user.company_description is cool, but user.company.description doesn't (unless company is a sort of namespace). Give context based on the view and/or the use case.

Short strings, such as "Do", "Yes", "Do it", "Got it", "Settings", "Go back" and "Support and Feedback" must be named with their value: do, yes, do_it and so on.

If you had the bad luck and the name of the string is a Java reserved word, prefix it with an underscore.

Arrays

String arrays should always use string resources and not string literals in its items. This makes translations easy, as arrays are not translated, but the strings do. This avoids problems of having arrays with different size or order in different languages.

<!-- This is cool -->
<string-array name="time_granularity">
    <item>@string/day</item>
    <item>@string/week</item>
    <item>@string/month</item>
</string-array>

<!-- This is not -->
<string-array name="time_granularity">
    <item>day</item>
    <item>week</item>
    <item>month</item>
</string-array>

The name of the arrays should not contain the word array, as they are in their own array namespace already.

Also, all arrays should be in a separate file from strings.

Misc

Unix newline convention

As the 3.206 Line of the POSIX standard establishes, all files must be ended with a newline.