Naming Conventions in Android


As a developer, there is a good probability that you have used libraries to make code cleaner and easier to use. In order to attain this we need to follow some basic naming conventions.Starting with layouts.

Layouts 

In developing android applications the first step is to create a layout which consists of widgets the application needs. Layout has some widgets and these should be followed with some basic naming conventions.Layout files should match the name of the Android components that they are intended for but moving the top level component name to the beginning. 

For example, if we are creating a layout for the SignInActivity, the name of the layout file should be activity_sign_in.xml.A slightly different case is when we are creating a layout that is going to be inflated by an Adapter, e.g to populate a ListView or Recyclerview. In this case, the name of the layout should start with item_

 

Class NameLayout Name
UserProfileActivity.javaactivity_user_profile.xml
SignUpFragement.javafragment_sign_up.xml
LogoutDialog.javadialog_logout.xml
AdapterViewItem.javaadapter_item_view.xml

 

Strings

String names start with a prefix that identifies the section they belong to. We use <HOW>_<DESCRIPTION> for strings naming. <HOW> to indicate reason of the string will be used & description give any extra information

For Example

PrefixDescription
error_An error message
msg_A regular information message
title_A title, i.e. a dialog title
action_An action such as “Save” or “Create

 

Drawables

We use <WHAT>_<DESCRIPTION> for strings naming. <WHAT> is Button,Dialog,Divider,Icon, etc & description give any extra information

 

Asset TypePrefixExample
Action barab_ab_stacked.9.png
Buttonbtn_btn_send_pressed.9.png
Dialogdialog_dialog_top.9.png
Dividerdivider_divider_horizontal.9.png
Iconic_ic_star.png
Menumenu_menu_submenu_bg.9.png
Notificationnotification_notification_bg.9.png
Tabstab_tab_pressed.9.png

 

Naming conventions for icons 

Asset TypePrefixExample
Iconsic_ic_star.png
Launcher iconsic_launcheric_launcher_calendar.png
Menu icons and Action Bar iconsic_menuic_menu_archive.png
Status bar iconsic_stat_notifyic_stat_notify_msg.png
Tab iconsic_tabic_tab_recent.png
Dialog iconsic_dialogic_dialog_info.png


Naming conventions for
selector states

StateSuffixExample
Normal_normalbtn_order_normal.9.png
Pressed_pressedbtn_order_pressed.9.png
Focused_focusedbtn_order_focused.9.png
Disabled_disabledbtn_order_disabled.9.png


Apps should only define a limited set of dimensions, which are constantly reused.

Dimensions

<WHAT>_<WHERE>_<SIZE> :

  • <WHAT> : It can be width(in dp), height (in dp), size (if width == height), margin(in dp), padding(in dp), elevation(in dp). text_size(in sp).
  • <WHERE>: It can be any specific item or remove this section if used throughout the application.
  • <SIZE>: It can be dp or sp

<!– size for both height and width –>

<dimen name=”size_10dp”> 10dp </dimen>

<dimen name=”size_20dp”> 20dp </dimen>

<!– margin –>

<dimen name=”margin_15dp”> 15dp </dimen>

<dimen name=”margin_20dp”> 20dp </dimen>

<!– padding–>

<dimen name=”padding_2dp”>2dp </dimen>

<dimen name=”padding_3dp”>3dp </dimen>

<!– width–>

<dimen name=”width_20dp”>20dp </dimen>

<dimen name=”width_30dp”>30dp </dimen>

<!– height–>

<dimen name=”height_20dp”>20dp </dimen>

<dimen name=”height_30dp”>30dp </dimen>

<!– text size–>

<dimen name=”text_size_15dp”>15dp </dimen>

<dimen name=”text_size_20dp”>20dp </dimen>

Menu files

Similar to layout files, menu files should match the name of the component. For example, if we are defining a menu file that is going to be used in the UserActivity, then the name of the file should be activity_user.xml

A good practice is to not include the word menu as part of the name because these files are already located in the menu directory.

Values files

Resource files in the values folder should be plural, e.g. strings.xml, styles.xml, colors.xml, dimens.xml, attrs.xml

Project Structure :

The basic build files above expects a default folder structure. Gradle follows the concept of convention over configuration, providing sensible default option values when possible. The basic project starts with two components called “source sets”, one for the main source code and one for the test code. These live respectively in:
  • src/main/
  • src/androidTest/
Inside each of these directories there are subdirectories for each source component. For both the Java and Android plugin, the location of the Java source code and the Java resources are:

  • java/
  • resources/
For the Android plugin, extra files and folders specific to Android:

  • AndroidManifest.xml
  • res/
  • assets/
  • aidl/
  • rs/
  • jni/
  • jniLibs/
This means that *.java files for the main source set are located in src/main/java and the main manifest is src/main/AndroidManifest.xml
 

Note: src/androidTest/AndroidManifest.xml is not needed as it is created automatically.

Class files

Class names are written in UpperCamelCase.

For classes that extend an Android component, the name of the class should end with the name of the component; for example: SignInActivity, SignInFragment, ImageUploaderService, ChangePasswordDialog.

Resources file names are written in lowercase_underscore.

Java Style Rules

Fields definition and naming

Fields should be defined at the top of the file and they should follow the naming rules listed below.

  • Private, non-static field names start with m.
  • Private, static field names start with s.
  • Other fields start with a lower case letter.
  • Static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.

Example:

public class MyClass {

    public static final int SOME_CONSTANT = 42;

    public int publicField;

    private static MyClass sSingleton;

    int mPackagePrivate;

    private int mPrivate;

    protected int mProtected;

}

Treat acronyms as words

GoodBad
XmlHttpRequestXMLHTTPRequest
getCustomerIdgetCustomerID
String urlString URL

Use spaces for indentation

  • Use 4 space indents for blocks:

if (x == 1)

 {

x++;

}

  • Use 8 space indents for line wraps:

Instrument i =

        someLongExpression(that, wouldNotFit, on, one, line);

Use standard brace style

Braces go on the same line as the code before them.

class MyClass {

    int func() {

        if (something) {

            // …

        } else if (somethingElse) {

            // …

        } else {

            // …

        }

    }

}

Braces around the statements are required unless the condition and the body fit on one line.If the condition and the body fit on one line and that line is shorter than the max line length, then braces are not required, e.g.

if (condition) body();

This is bad:

if (condition)

    body();  // bad!

 

Annotations practices

According to the Android code style guide, the standard practices for some of the predefined annotations in Java are:

  • @Override: The @Override annotation must be used whenever a method overrides the declaration or implementation from a super-class. For example, if you use the @inheritdocs Javadoc tag, and derive from a class (not an interface), you must also annotate that the method @Overrides the parent class’s method.
  • @SuppressWarnings: The @SuppressWarnings annotation should only be used under circumstances where it is impossible to eliminate a warning. If a warning passes this “impossible to eliminate” test, the @SuppressWarnings annotation must be used, so as to ensure that all warnings reflect actual problems in the code.

Annotations style

Classes, Methods and Constructors

When annotations are applied to a class, method, or constructor, they are listed after the documentation block and should appear as one annotation per line .

/* This is the documentation block about the class */

@AnnotationA

@AnnotationB

public class MyAnnotatedClass { }

Fields

Annotations applying to fields should be listed on the same line, unless the line reaches the maximum line length.

@Nullable @Mock DataManager mDataManager;

 

Log sparingly

While logging is necessary, it has a negative impact on performance and loses its usefulness if not kept reasonably terse. The logging facilities provide five different levels of logging:

  • ERROR: Use when something fatal has happened, that is, something will have user-visible consequences and won’t be recoverable without deleting some data, uninstalling apps, wiping the data partitions, or reflashing the entire device (or worse). This level is always logged. Issues that justify some logging at the ERROR level are good candidates to be reported to a statistics-gathering server.
  • WARNING: Use when something serious and unexpected happened, that is, something that will have user-visible consequences but is likely to be recoverable without data loss by performing some explicit action, ranging from waiting or restarting an app all the way to re-downloading a new version of an app or rebooting the device. This level is always logged. Issues that justify logging at the WARNING level might also be considered for reporting to a statistics-gathering server.
  • INFORMATIVE: Use to note that something interesting happened, that is, when a situation is detected that is likely to have widespread impact, though isn’t necessarily an error. Such a condition should only be logged by a module that believes that it’s the most authoritative in that domain (to avoid duplicate logging by nonauthoritative components). This level is always logged.
  • DEBUG: Use to further note what’s happening on the device that could be relevant to investigate and debug unexpected behaviors. Log only what’s needed to gather enough information about what’s going on with your component. If your debug logs are dominating the log, then you should use verbose logging.
    This level is logged even on release builds, and is required to be surrounded by an if (LOCAL_LOG) or if LOCAL_LOGD) block, where LOCAL_LOG[D] is defined in your class or subcomponent, so that there’s a possibility to disable all such logging. Therefore, there must be no active logic in an if (LOCAL_LOG) block. All the string building for the log also needs to be placed inside the if (LOCAL_LOG) block. Don’t refactor the logging call out into a method call if it’s going to cause the string building to take place outside of the if (LOCAL_LOG) block.
    There’s some code that still says if (localLOGV). This is considered acceptable as well, although the name is nonstandard.
  • VERBOSE: Use for everything else. This level is only logged on debug builds and should be surrounded by an if (LOCAL_LOGV) block (or equivalent) so that it can be compiled out by default. Any string building is stripped out of release builds and needs to appear inside the if (LOCAL_LOGV) block.

Use the logging methods provided by the Log class to print out error messages or other information that may be useful for developers to identify issues:

  • Log.v(String tag, String msg) (verbose)
  • Log.d(String tag, String msg) (debug)
  • Log.i(String tag, String msg) (information)
  • Log.w(String tag, String msg) (warning)
  • Log.e(String tag, String msg) (error)

 

As a general rule, we use the class name as tag and we define it as a static final field at the top of the file. For example:

public class MyClass {

    private static final String TAG = MyClass.class.getSimpleName();

    public myMethod() {

        Log.e(TAG, “My error message”);

    }

}

VERBOSE and DEBUG logs must be disabled on release builds. It is also recommended to disable INFORMATION, WARNING and ERROR logs but you may want to keep them enabled if you think they may be useful to identify issues on release builds. If you decide to leave them enabled, you have to make sure that they are not leaking private information such as email addresses, user ids, etc.

To only show logs on debug builds:

if (BuildConfig.DEBUG) Log.d(TAG, “The value of x is “ + x);

 

Class member ordering

There is no single correct solution for this but using a logical and consistent order will improve code learnability and readability. It is recommendable to use the following order:

  1. Constants
  2. Fields
  3. Constructors
  4. Override methods and callbacks (public or private)
  5. Public methods
  6. Private methods
  7. Inner classes or interfaces

Example:

public class MainActivity extends Activity {

    private static final String TAG = MainActivity.class.getSimpleName();

    private String mTitle;

    private TextView mTextViewTitle;

    @Override

    public void onCreate() {        

    }

 public void setTitle(String title) {

     mTitle = title;

    }

    private void setUpView() {

    }

    static class AnInnerClass {

    }

}

if your class is extending an Android component such as an Activity or a Fragment, it is a good practice to order the override methods so that they match the component’s lifecycle. For example, if you have an Activity that implements onCreate(), onDestroy(), onPause() and onResume(), then the correct order is:

public class MainActivity extends Activity {

//Order matches Activity lifecycle

    @Override

    public void onCreate() {}

    @Override

    public void onResume() {}

    @Override

    public void onPause() {}

    @Override

    public void onDestroy() {}

}

Parameter ordering in methods

When programming for Android, it is quite common to define methods that take a Context. If you are writing a method like this, then the Context must be the first parameter.The opposite case are callback interfaces that should always be the last parameter.

Examples:

// Context always goes first

public User loadUser(Context context, int userId);

// Callbacks always go last

public void loadUserAsync(Context context, int userId, UserCallback callback);

String constants, naming, and values

Many elements of the Android SDK such as SharedPreferences, Bundle, or Intent use a key-value pair approach so it’s very likely that even for a small app you end up having to write a lot of String constants.

When using one of these components, you must define the keys as a static final fields and they should be prefixed as indicated below.

ElementField Name Prefix
SharedPreferencesPREF_
BundleBUNDLE_
Fragment ArgumentsARGUMENT_
Intent ExtraEXTRA_
Intent ActionACTION_


Example:Note that the arguments of a Fragment – Fragment.getArguments() – are also a Bundle. However, because this is a quite common use of Bundles, we define a different prefix for them.

// Note the value of the field is the same as the name to avoid duplication issues

static final String PREF_EMAIL = “PREF_EMAIL”;

static final String BUNDLE_AGE = “BUNDLE_AGE”;

static final String ARGUMENT_USER_ID = “ARGUMENT_USER_ID”;

// Intent-related items use full package name as value

static final String EXTRA_SURNAME = “com.myapp.extras.EXTRA_SURNAME”;

static final String ACTION_OPEN_USER = “com.myapp.action.ACTION_OPEN_USER”;

 

Arguments in Fragments and Activities

When data is passed into an Activity or Fragment via an Intent or a Bundle, the keys for the different values must follow the rules described in the section above.

When an Activity or Fragment expects arguments, it should provide a public static method that facilitates the creation of the relevant Intent or Fragment.

In the case of Activities the method is usually called getStartIntent():

public static Intent getStartIntent(Context context, User user) {

Intent intent = new Intent(context, ThisActivity.class);

intent.putParcelableExtra(EXTRA_USER, user);

return intent;

}

For Fragments it is named newInstance() and handles the creation of the Fragment with the right arguments:

public static UserFragment newInstance(User user) {

UserFragment fragment = new UserFragment();

Bundle args = new Bundle();

args.putParcelable(ARGUMENT_USER, user);

fragment.setArguments(args)

return fragment;

}

Note 1: These methods should go at the top of the class before onCreate().

Note 2: If we provide the methods described above, the keys for extras and arguments should be private because there is not need for them to be exposed outside the class.

Xml Rules

Use self closing tags

When an XML element doesn’t have any contents, you must use self closing tags.This is good:

<TextView

android:id=“@+id/text_view_profile”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content” />

This is bad :

<!– Don\’t do this! –>

<TextView

    android:id=“@+id/text_view_profile”

    android:layout_width=“wrap_content”

    android:layout_height=“wrap_content” >

</TextView>

Resources naming

Resource IDs and names are written in lowercase_underscore.

ID naming

IDs should be prefixed with the name of the element in lowercase underscore. For example:

ElementPrefix
TextViewtext_
ImageViewimage_
Buttonbutton_
Menumenu_


<
ImageViewImage view example:

    android:id=“@+id/image_profile”

    android:layout_width=“wrap_content”

    android:layout_height=“wrap_content” />

Menu example:

<menu>

    <item

        android:id=“@+id/menu_done”

        android:title=“Done” />

</menu>