# Code and Naming Conventions - Android
## 1. Project Stucture
New projects should follow the [Android Gradle project structure](http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Project-Structure) that is defined on the Android Gradle plugin user guide.
## 1.1 Naming
All source files must be encoded as UTF-8. And resource names following below a simple convention.
> ``<what>_<where>_<description>_<size/state>``
Let’s first describe every element briefly. After the advantages, we’ll see how this applies to each resource type.
| Keywoard | Description |
|----------------- |--------------|
| ``<what>`` | Indicate what the resource actually represents, often a standard Android view class. Limited options per resource type. |
| ``<where>`` | Describe where it logically belongs in the app or feature. |
|``<description>`` | Differentiate multiple elements in one screen. |
|``<size/state>`` | The size is based on bucket and the state is based on the event or functionality. Optionally used for drawables, layouts, and dimensions. |
### 1.1.1 Class File
Class names are written in [UpperCamelCase](http://en.wikipedia.org/wiki/CamelCase) name of the top-level class, follow below simple convention.
> ``<What><Where>``
```
// SignInActivity.kt
class SignInActivity { }
```
```
// TransferFragment.kt
class TransferFragment {}
```
If a source file contains multiple top-level declarations (which should be avoided if possible), choose a name that best describes the contents of the file.
```
// AccountsAdapter.kt
fun AccountsEntity.toModel() { /* ... */ }
fun AccountsModel.toEntity() { /* ... */ }
```
Model and data classes are exceptions:
```
// Account.kt
data class Account { }
```
### 1.1.2 Resources File
Resources file names are written in **lowercase_underscore**.
#### 1.1.2.1 Drawable files
Naming conventions for drawables:
> ``<what>_<descriptions>_<size/state>``
| Asset Type | Prefix | Example |
| ------------ | ------------ | -------------------------------- |
| Action bar | ab_ | ab_stacked.png |
| Button | btn_ | btn_send_pressed.png |
| Dialog | dialog_ |dialog_top.png |
| Divider | divider_ | divider_horizontal.png |
| Icon | ic_ | ic_star.png |
| Menu | menu_ | menu_submenu_background.png |
| Notification | notification_ | notification_item_background.png |
| Tabs | tab_ | tab_regular_pressed.png |
#### 1.1.2.2 Icon Files
Naming conventions for [icons](http://developer.android.com/design/style/iconography.html):
> ``<what>_<descriptions>``
| Asset Type | Prefix | Example |
| --------------------------------- | -------------- | --------------------------- |
| Icons | ic_ | ic_star.png |
| Launcher icons | ic_launcher | ic_launcher_calendar.png |
| Menu icons and Action Bar icons | ic_menu | ic_menu_archive.png |
| Status bar icons | ic_stat_notify | ic_stat_notify_massage.png |
| Tab icons | ic_tab | ic_tab_recent.png |
| Dialog icons | ic_dialog | ic_dialog_info.png |
#### 1.1.2.3 Font Files
Naming conventions for fonts:
> ``<what>_<descriptions>``
example:
``arial_italic, tt_common_regular``
#### 1.1.2.4 Anim Files
Naming conventions for anims:
> ``<what>_<descriptions>``
example:
``anim_fade_in, anime_fade_out``
#### 1.1.2.2 Layout Files
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. The naming follow bellow convention:
> ``<what><Where>``
| Component | Class Name | Layout Name |
| ---------------- | ------------------------------------ | ------------------------------ |
| Activity | UserProfileActivity | activity_user_profile.xml |
| Fragment | SignUpFragment | fragment_sign_up.xml |
| Dialog | ChangePasswordDialog | dialog_change_password.xml |
| AdapterView item | ProductViewHolder | item_product.xml |
| Partial layout | Partial layout for DashboardFragment | content_dashboard_favorite.xml |
#### 1.1.2.3 Menu Files
Menu files should match the name of the component and following by the feature. 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 ``menu_user.xml``
#### 1.1.2.4 Value Files
Resource files in the values folder should be plural, e.g. ``strings.xml``, ``styles.xml``, ``colors.xml``, ``dimens.xml``, ``attrs.xml``.
#### 1.1.2.5 Navigation Files
Navigation files should match the name of the component and following by the feature, e.g. ``nav_graph_transfer.xml``, ``nav_graph_sign_up.xml``.
#### 1.1.2.5 Mipmap Files
TBD
#### 1.1.2.6 Raw Files
TBD
#### 1.1.2.7 Transition Files
TBD
#### 1.1.2.8 XML Files
Naming conventions for XML:
> ``<what>_<description>``
example:
``lint``
### 1.1.3 ID or Resources
#### 1.1.3.1 ID attribute
Naming conventions for ID ``(android:id="@+id/)``:
Data Binding:
> ``<descriptions>``
Others:
> ``<what>_<where>_<descriptions>``
| Widget Type | Type | Prefix | Example |
| ---------------- | ------------ | ------- |------------------------ |
| All | Data Binding | --- | name, address |
| TextView | Others | tv_ | tv_name |
| EditText | Others | et_ | et_username |
| Linearlayout | Others | ll_ | ll_user_container |
| ConstraintLayout | Others | cl_ | cl_account_container |
#### 1.1.3.2 Colors
Naming conventions for colors:
> ``<what><Where><Description><State>``
example:
``colorButtonPrimaryPressed, colorCardViewBorder``
#### 1.1.3.3 Styles
Naming conventions for styles:
Themes :
> ``<What>.<BankMandiri>.<Where>``
Themes for spesific project:
> ``<What>.<ProjectName>.<Where>``
Widget:
> ``<What>.<BankMandiri>.<Where>.<Descriptions>``
example:
``AppTheme.BankMandiri.Base, AppTheme.Everest.Splash, TextAppearance.BankMandiri.TextView, TextAppearance.Everest.TextView``
#### 1.1.3.4 Strings
Naming conventions for strings:
> ``<where>_<descriptions>``
example:
``login_username_hint, transfer_amount_hint``
#### 1.1.3.5 Dimens
Naming conventions for dimens:
Commons:
> ``<where>_<description>_<what><size>``
Features:
> ``<where>_<what>_<descriptions>_<size>``
example:
``button_height, textview_textsize_small, transfer_account_margin_left``
#### 1.1.4 States
Naming conventions for selector states:
| State | Suffix | Example |
| ---------- | ---------- | ----------------------- |
| Normal | _normal | btn_order_normal.png |
| Pressed | _pressed | btn_order_pressed.png |
| Focused | _focused | btn_order_focused.png |
| Disabled | _disabled | btn_order_disabled.png |
| Selected | _selected | btn_order_selected.png |
#### 1.1.5 Special Characters
#### 1.1.5.1 Whitespace characters
Aside from the line terminator sequence, the **ASCII horizontal space character** ``(0x20)`` is the only whitespace character that appears anywhere in a source file. This implies that:
* All other whitespace characters in string and character literals are escaped.
* Tab characters are not used for indentation.
#### 1.1.5.2 Special escape sequences
For any character that has a special escape sequence (``\b``, ``\n``, ``\r``, ``\t``, ``\'``, ``\"``, ``\\``, and ``\$``), that sequence is used rather than the corresponding Unicode (e.g., ``\u000a``) escape.
#### 1.1.5.3 Non-ASCII characters
For the remaining non-ASCII characters, either the actual Unicode character (e.g., ``∞``) or the equivalent Unicode escape (e.g., ``\u221e``) is used. The choice depends only on which makes the code easier to read and understand. Unicode escapes are discouraged for printable characters at any location and are strongly discouraged outside of string literals and comments.
| Example | Discussion |
| --------------------------------- | ------------------------------------------------------------------- |
| val unitAbbrev = "μs" | Best: perfectly clear even without a comment |
| val unitAbbrev = "\u03bcs" // μs | Poor: there’s no reason to use an escape with a printable character |
| val unitAbbrev = "\u03bcs"` | Poor: the reader has no idea what this is |
return "\ufeff" + content | Good: use escapes for non-printable characters, and comme |
## 2. Class Structure
A kotlin file comprises the following, in order:
* Copyright and/or license header (optional)
* File-level annotations
* Package statement
* Import statements
* Top-level declarations
* Exactly one blank line separates each of these sections.
### 2.1 Copyright / License
If a copyright or license header belongs in the file it should be placed at the immediate top in a multi-line comment.
```
/*
* Copyright 2019 PT Bank Mandiri (Persero) Tbk.
*
* ...
*/
```
### 2.2 File-level annotations
Annotations with the "file" [use-site target](https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets) are placed between any header comment and the package declaration.
### 2.3 Package statement
The package statement is not subject to any column limit and is never line-wrapped, multiples words concatenated together without underscores or hyphens.
```
com.example.fundstransfer
```
### 2.3 Import statements
Import statements for classes, functions, and properties are grouped together in a single list and ASCII sorted.
Wildcard imports (of any type) are **not allowed**, except for data binding.
Similar to the package statement, import statements are not subject to a column limit and they are never line-wrapped.
### 2.4 Top-level declarations
A kotlin file can declare one or more types, functions, properties, or type aliases at the top-level.
The contents of a file should be focused on a single theme. Examples of this would be a single public type or a set of extension functions performing the same operation on multiple receiver types. Unrelated declarations should be separated into their own files and public declarations within a single file should be minimized.
No explicit restriction is placed on the number nor order of the contents of a file.
Source files are usually read from top-to-bottom meaning that the order, in general, should reflect that the declarations higher up will inform understanding of those farther down. Different files may choose to order their contents differently. Similarly, one file may contain 100 properties, another 10 functions, and yet another a single class.
What is important is that each class uses **some** logical order, which its maintainer could explain if asked. For example, new functions are not just habitually added to the end of the class, as that would yield “chronological by date added” ordering, which is not a logical ordering.
### 2.5 Class member ordering
The order of members within a class follow the same rules as the top-level declarations.
## 3.1 Formating
### 3.1.1 Kotlin
#### 3.1.1.1 Braces
Braces are not required for `when` branches and `if` statement bodies which have no `else if/else` branches and which fit on a single line.
```
if (string.isEmpty()) return
when (value) {
0 -> return
// …
}
```
Braces are otherwise required for any `if`, `for`, `when` branch, `do`, and `while` statements, even when the body is empty or contains only a single statement.
```
if (string.isEmpty())
return // WRONG!
if (string.isEmpty()) {
return // Okay
}
```
##### 3.1.1.1.1 Non-empty blocks
Braces follow the `Kernighan and Ritchie` style ("Egyptian brackets") for nonempty blocks and block-like constructs:
* No line break before the opening brace.
* Line break after the opening brace.
* Line break before the closing brace.
* Line break after the closing brace, only if that brace terminates a statement or terminates the body of a function, constructor, or named class. For example, there is no line break after the brace if it is followed by `else` or a comma.
```
return Runnable {
while (condition()) {
foo()
}
}
return object : MyClass() {
override fun foo() {
if (condition()) {
try {
something()
} catch (e: ProblemException) {
recover()
}
} else if (otherCondition()) {
somethingElse()
} else {
lastThing()
}
}
}
```
A few exceptions for enum classes are given below.
##### 3.1.1.1.2 Empty blocks
An empty block or block-like construct must be in `Kernighan and Ritchie` style.
```
try {
doSomething()
} catch (e: Exception) {} // BAD
```
```
try {
doSomething()
} catch (e: Exception) {
} // GOOD
```
##### 3.1.1.1.2 Expressions
An `if/else` conditional that is used as an expression may omit braces only if the entire expression fits on one line.
```
val value = if (string.isEmpty()) 0 else 1 // GOOD
```
```
val value = if (string.isEmpty()) // BAD
0
else
1
```
```
val value = if (string.isEmpty()) { // GOOD
0
} else {
1
}
```
#### 3.1.1.2 Indentation
Use four(4) sapces for indentations. Each time a new block or block-like construct is opened, the indent increases by four `spaces`. When the block ends, the indent returns to the previous indent level. The indent level applies to both code and comments throughout the block.
```
fun sum(valueA: Int, valueB: Int): Int {
return valueA + ValueB
}
```
```
if (elements != null) {
for (element in elements) {
// ...
}
}
```
```
private fun getSharedPreferences() =
context.getSharedPreferences(SHARED_PREFERENCES_FILENAME, Context.MODE_PRIVATE)
```
#### 3.1.1.3 One statement per line
Each statement is followed by a line break. Semicolons are not used.
```
val total = numberA + numberB
val average = total / 2
...
```
#### 3.1.1.4 Line wrapping
Code has a column limit of **120** characters. Except as noted below, any line that would exceed this limit must be line-wrapped, as explained below.
Exceptions:
* Lines where obeying the column limit is not possible (for example, a long URL in KDoc)
* `package` and `import` statements
* Command lines in a comment that may be cut-and-pasted into a shell
#### 3.1.1.5 Where to break
The prime directive of line-wrapping is: prefer to break at a higher syntactic level. Also:
* When a line is broken at a non-assignment operator the break comes before the symbol.
* This also applies to the following “operator-like” symbols:
* The dot separator (`.`).
* The two colons of a member reference (`::`).
* When a line is broken at an assignment operator the break comes after the symbol.
```
randomStringList
.any { !it.isNullOrBlank() }
```
```
inline fun <reified T: Any> Gson.fromJson(json: JsonElement): T = this.fromJson(json, T
::class.java)
```
```
val anchor = owner
?.firstChild!!
.siblings(forward = true)
.dropWhile { it is PsiComment || it is PsiWhiteSpace }
```
```
val stream =
Files.newInputStream(Paths.get("/some/file.txt"))
```
* A method or constructor name stays attached to the open parenthesis (`(`) that follows it.
```
fun drawSquare(
x = 10,
y = 10,
width = 100,
height = 100
)
```
* A comma (`,`) stays attached to the token that precedes it.
```
fun transfer(source: Account, destination: Account, amount: Double,
currency: String)
```
* A lambda arrow (`->`) stays attached to the argument list that precedes it.
```
appendCommaSeparated(properties) { prop ->
val propertyValue = prop.get(obj)
}
```
### 3.1.2 XML