Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/UI guideline #7

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
80b8f31
Add basics of the UI guideline
Jun 24, 2021
92639a2
Update ui-guideline.md
mgurdogan Jun 24, 2021
fa79db7
add the advantages of the view binding
mgurdogan Jun 29, 2021
772df2a
update ui-guideline.md
mgurdogan Jun 29, 2021
b5ee596
Update ui-guideline.md
mgurdogan Jun 29, 2021
53fefb0
Update ui-guideline.md
mgurdogan Jun 29, 2021
1a757f6
Update ui-guideline.md
mgurdogan Jun 29, 2021
90d60ff
Update ui-guideline.md
mgurdogan Jun 29, 2021
a471c8e
Update ui-guideline.md
mgurdogan Jul 1, 2021
e782af7
Update ui-guideline.md
mgurdogan Jul 1, 2021
89d292c
Update ui-guideline.md
mgurdogan Jul 1, 2021
b5f2b74
Update ui-guideline.md
mgurdogan Jul 1, 2021
0a75aad
Update ui-guideline.md
mgurdogan Jul 6, 2021
ce60d12
Update ui-guideline.md
mgurdogan Jul 6, 2021
120e233
Update ui-guideline.md
mgurdogan Jul 6, 2021
69ce3d8
Update ui-guideline.md
mgurdogan Jul 6, 2021
3d031f0
Update ui-guideline.md
mgurdogan Jul 8, 2021
520b5c3
Update ui-guideline.md
mgurdogan Jul 8, 2021
5b389c3
Update ui-guideline.md
mgurdogan Jul 8, 2021
79a6e65
Update ui-guideline.md
mgurdogan Jul 27, 2021
35aa247
Update ui-guideline.md
mgurdogan Jul 27, 2021
45eb247
Update ui-guideline.md
mgurdogan Aug 10, 2021
9574223
Update ui-guideline.md
mgurdogan Aug 12, 2021
9392686
Update ui-guideline.md
mgurdogan Aug 17, 2021
aa61eb9
Update ui-guideline.md
mgurdogan Aug 17, 2021
454eb2a
Update ui-guideline.md
mgurdogan Aug 17, 2021
61144c9
Update ui-guideline.md
mgurdogan Aug 17, 2021
befaa8e
Update ui-guideline.md
mgurdogan Aug 17, 2021
51f4064
Update ui-guideline.md
mgurdogan Aug 26, 2021
8a529f0
Update ui-guideline.md
mgurdogan Aug 26, 2021
15300cc
Update ui-guideline.md
mgurdogan Aug 26, 2021
fdd41e1
Update ui-guideline.md
mgurdogan Aug 26, 2021
f0d6677
Update ui-guideline.md
mgurdogan Aug 26, 2021
96aed76
Update ui-guideline.md
mgurdogan Sep 14, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
262 changes: 262 additions & 0 deletions ui-guideline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
<h1 align="center">UI Guideline</h1></br>
<p align="center">
You can find out the suggestions and things that we are paying attention when creating the UI elements.
</p>

### Table of Contents
1. [Creating the User Interfaces](#creating_layouts)
2. [Custom Views](#custom_views)
3. [Debugging the Views](#debugging_views)
4. [Theming](#theming)
5. [Animations](#animations)
6. [Designing the Smooth Splash Screen](#splash_screen)
7. [Material Design and Dark Mode](#material_design)
<a name="creating_layouts"></a>
## Creating the User Interfaces

- We are creating the layout files using ConstraintLayout.
- When using the ConstraintLayout, we take care to support layout mirroring by applying [these rules. (developer.android.com)](https://developer.android.com/training/basics/supporting-devices/languages#MirroringUpdateResources)
- We avoid from using the nested views as much as we can. Instead of that, we prefer the flat view hierarchy.
- We prefer to use the drawables(shapes, vectordrawables etc.) instead of Images.
- We always stay away from using the hardcoded values inside the XML layouts. We prefer to get the values from the resource files like **styles.xml** , **strings.xml** , **dimens.xml**.
- One of our most important aims when creating a layout is reusability and consistency. Therefore, we take care to use custom views and styles for using common UI elements.
- We always aim to supporting different pixel densities and providing alternative bitmaps for the different screen sizes.
- We are using the AppCompat libraries because,
Appcompats are (AppCompatTextView,AppCompatButton etc.) supports compatible features on older versions of the platform so they allows access to new APIs on older API versions of the platform.
[Further Information (developer.android.com)](https://developer.android.com/jetpack/androidx/releases/appcompat)
- We always aim for the reusability, we are using the include tag, or we are creating the Custom Views or we are using the styles.
- We always stay away from use the RecyclerView inside NestedScrollView because it can disable the "recycle" function of the RecyclerView.
- We are using the Shape Drawables instead of the PNG or WEBP files.
** Regarding the Android Documentation, we recommend to limit a vector image to a maximum **200x200** dp, otherwise it can take too long to draw, because since the vector graphics are rendered at runtime, rendering of a VectorDrawable will be slower than the PNG file.

##

### Our rule set when choosing SVG is
- If it's smaller than the 200*200dp
- If it's not contains so many detail on itself
- If it's not contains any gradient tag. (You can use the VectorDrawable which contains a gradient tag by creating separate VectorDrawables for the different API levels. so that you can use the VectorDrawable which contains a gradient tag for the API >=24, and you can use the other one which doesn't contain the gradient tag for lower API levels. )

##

### We prefer the View Binding library for binding the views.
#### What are the benefits of the View Binding?

View Binding generates binding classes for all layouts in the app,
so you don't have to use the findViewById method anymore, instead of this
you can simply call the view by typing binding.viewName.tag
View bindings are type-safe, it will always create the object according to the
view types. So if you created a Button in the layout, then the
ViewBinding creates a Button object inside the binding instance
and it will use the id of the View as the reference name
of the generated object.

**The advantages of the view binding are**

- It only references the IDs from the current layout.
- Kotlin Synthetics only supports Kotlin, while ViewBinding supports both Kotlin & Java.
- It's always null safe and it requires a lesser code than the ButterKnife.


You can take a look for more [detailed comprasion (developer.android.com)](https://developer.android.com/topic/libraries/view-binding)

##

<a name="custom_views"></a>
## Custom Views
Custom views are the way to create the views with custom functions and visuals on Android SDK.


Regarding the Android documentation, Custom views should;

- Conform to Android standards
- Provide custom styleable attributes that work with Android XML
layouts
- Send accessibility events
- Be compatible with multiple Android platforms.

#### Rule Set for choosing the way that provides us the Reusability
#### There are alternative ways to create reusable views, and we have a rule set when we are trying to choose one of them.

- If the view is constant and if there is no logic inside of them, then we prefer to use the __include tags__.
- If the view is not constant and not contains any logic, and also if we are able to handle this by using the styling, then we prefer to use the __styles__.
- If the view has its own business logic with complex views, then we prefer to use the __Custom Views__.


[Creating a View Class (developer.android.com)](https://developer.android.com/training/custom-views/create-view)

- We extend the Custom View classes from the closest native Android View class. It provides the functionality of the parent view. So, if you planning to create a custom TextView that has more features than the regular TextView, you should extend your Custom View from the TextView class.
- We use the ```android:contentDescription``` attribute to provide an experience with the [Accesibility. (android.com)](https://www.android.com/accessibility/)
- We pay attention to checking the isInEditMode variable before doing the data related things. If you pay attention to the edit mode variable, you will be able to see the Preview of your Custom View on the Preview screens.
- We create public functions inside the custom view for the necessary things that should be accessible by the Developer.

<a name="debugging_views"></a>
## Debugging the Views

We inspect the GPU Overdraw issue by enabling the **[Debug GPU Overdraw (developer.android.com)](https://developer.android.com/topic/performance/rendering/inspect-gpu-rendering)** preference on the Developer Options on our Android devices, also we are checking the UI issues by using the **[Layout Inspector (developer.android.com)](https://developer.android.com/studio/debug/layout-inspector)**


<a name="theming"></a>
## Theming
- We always stay away from using the hardcoded values inside the XML layouts. We prefer to get the values from the resource files like **styles.xml** , **strings.xml**.

It provides us App-level consistency and it makes it easy to create new layouts or views.





### There are some different XML files to provide a theme experience.

| Name | Purpose |
|-------------|---------|
| styles | Stores the defined styles, which are attributes of the Views. |
| colors | Contains all the defined color codes used by the Application. |
| themes | Themes are the parents of the styles. All the screens can have different themes and the themes file contains all the defined theme values. |
| dimens | Contains all the defined dimension values inside of it. So that we can use them for the styling. |
| strings | Contains all the string values used by the Application, also it can be used for Localization. |

[Themes versus Styles (developer.android.com)](https://developer.android.com/guide/topics/ui/look-and-feel/themes#versus)


### Benefits of the theming.


- Scenario: We want to have two TextViews with a few attributes in the same layout.



We were going to have this kind of code for this purpose without theming.
```gradle
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<androidx.appcompat.widget.AppCompatTextView
android:background="@drawable/bg_purple_radius"
android:fontFamily="@font/example_font"
android:gravity="start"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:lines="1"
android:marqueeRepeatLimit="marquee_forever"
android:textAllCaps="true"
android:textColor="@color/white"
android:textSize="16sp"
android:visibility="visible"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:background="@drawable/bg_purple_radius"
android:fontFamily="@font/example_font"
android:gravity="start"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:lines="1"
android:marqueeRepeatLimit="marquee_forever"
android:textAllCaps="true"
android:textColor="@color/white"
android:textSize="16sp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
```

#### But what if we used the theming?

We will just define the attributes for single time in the styles.xml,

```gradle
<style name="MyPerfectTextView">
<item name="android:textColor">@color/white</item>
<item name="android:textSize">16sp</item>
<item name="android:visibility">visible</item>
<item name="android:fontFamily">@font/example_font</item>
<item name="android:textAllCaps">true</item>
<item name="android:gravity">start</item>
<item name="android:background">@drawable/bg_purple_radius</item>
<item name="android:lines">1</item>
<item name="android:marqueeRepeatLimit">"marquee_forever</item>
</style>

```

It's our new Layout file!

```gradle

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<androidx.appcompat.widget.AppCompatTextView
style="@style/MyPerfectTextView"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/MyPerfectTextView"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

```

So, in the end, when we think about it on the whole app level, it provides us cleaner, more readable, and reusable codes.

##

<a name="animations"></a>
## Animations
We prefer to use the MotionLayout for the Animations. MotionLayout is a layout which is a subclass of the ConstraintLayout, and has a backward compatibility to API level 14. You can create your animations by using the MotionScenes, then you can apply your MotionScenes to the MotionLayout by using the "app:layoutDescription" tag.

[For Further Information (developer.android.com)](https://developer.android.com/training/constraint-layout/motionlayout)


##

<a name="splash_screen"></a>
## Designing the Smooth Splash Screen

Splash Screen is the first screen visible to the user when the application is launched.

We don't have any Splash Mechanism on Android before the API 31, There is a white screen, or UI lag on most of the apps when they try to Render the Splash Screen.
But we think that the Splash screen should be fast, smooth, and lightweight. So, the idea is it should be fast and the reason for the UI lag is rendering the Splash XML view. So, what we are doing is we are not using anything that extends from the View, also we are not setting any layout to the Splash Activity.

In short, the Splash Activity doesn't have any call to setContentView function.


We use the theming on the Splash activities or fragments for providing a smooth app launch experience.

Firstly we create a drawable that just holds an item that contains a bitmap of the app logo, then we are creating a style that uses this drawable as its "android:background" then we are setting this style as the theme of our Splash Activity.

In the end, the Activity doesn't have any setContentView block or any rendering process. Since the Splash Activity doesn't have anything to render it works super fast.

##

<a name="material_design"></a>
## Material Design and Dark Mode
> Android users expect your app to look and behave in a way that’s consistent with the platform. You should follow material
> design guidelines for visual and navigation patterns… --[(d.android.com/design)](https://d.android.com/design)

We recommend using the Material Design Components.

The material components are a way to provide easily customizable UI components with consistency.

The material components also provide you the default styles and some built-in attributes, without the material components we were required to create some shape drawable for almost every customization on the Views.

For example, for adding some radius corners to a Button, we were required to create some XML drawable files..

but with Material Components, it's simple as possible. We just making the same thing by just using this attributes with Material Components.

```gradle
<com.google.android.material.button.MaterialButton
....
style="@style/Widget.MaterialComponents.Button"
app:cornerRadius=".."
app:strokeColor="@color/colorPrimary"/>
```

The material theme also has a dark theme guide and it's easy to implement the dark mode on the Material Components.
[https://material.io](https://material.io/design/color/dark-theme.html#usage )