Login Screen in Android is one of the most used feature in application development. Almost every application has a Login and Register functionality in it. In this Kotlin Android login example I am going to tell you how you can make a simple and attractive Login Screen for your android applications. So lets start how to make login screen in Kotlin Language using Android Studio.
KOTLIN LOGIN EXAMPLE
How To Make Login Screen In Kotlin:
To make a Kotlin login page first of all open your Android Studio and make a new Project. Name it “LoginApp” or give any name of your choice. Select KOTLIN as the default language for your project.
Before start coding first define these colors in your “colors.xml” file. You can find this file in your “res” folder under “values” directory.
1 2 3 |
<color name="colorDefault">#9e9e9e</color> <color name="colordarkblue">#00008b</color> <color name="colorwhiteblueshade">#DF949DCD</color> |
Now we need to add some images for the email and password fields. Right click on drawable folder and select New then select Vector Asset. Select your desired icon from the list and press OK. Repeat the same procedure again and select another icon of your choice for the password field. Take one more icon “cancel” or “remove” whatever you like from the list. We will display it on the right side of the Text fields to remove the text. Now you can see all the three icons inside your drawable folder. Double click on the icon and it will open the vector properties for that icon. Here you have to change the property android:tint with android:tint=”#9e9e9e”.
Android Login
activity_main.xml
Come to activity_main.xml file and first of all change the default Constraint Layout to Relative Layout. We will add some views in our activity_main.xml file. These views are:
1- Toolbar
2-EditText
3-TextView
4-Button
5-Radio Button
First we will design our Toolbar. For doing so first go to the styles.xml file under values folder. Change the default with this one.
1 |
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> |
We give an id for the toolbar and define its height and width. After adding text and some other properties our toolbar will be like this.
1 2 3 4 5 6 7 8 |
<androidx.appcompat.widget.Toolbar android:id="@+id/toolbar_login" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFFFFF" app:title=" Log In" app:titleTextColor="#000000" /> |
Similarly we will create other views and give them their respective ids, height/width and other properties. The final activity_main.xml file will look like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar_login" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFFFFF" app:title=" Log In" app:titleTextColor="#000000" /> <EditText android:id="@+id/email" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/toolbar_login" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_marginTop="60dp" android:drawablePadding="10dp" android:hint="Email" android:inputType="textEmailAddress" android:paddingBottom="20dp"> </EditText> <EditText android:id="@+id/password" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/email" android:layout_marginLeft="20dp" android:layout_marginTop="11dp" android:layout_marginRight="20dp" android:drawablePadding="10dp" android:paddingBottom="20dp" android:hint="Password" android:inputType="textPassword" /> <TextView android:id="@+id/forgot_password" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/password" android:layout_marginLeft="20dp" android:layout_marginTop="25dp" android:text="Forgot Password" android:textColor="#8F8686" android:textSize="15dp" /> <Button android:id="@+id/login_button" android:layout_width="match_parent" android:layout_height="60dp" android:layout_below="@+id/forgot_password" android:layout_marginTop="30dp" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:text="Log In" android:textColor="#FFFFFF" android:textSize="20dp" android:textAllCaps="false" android:background="#00008b" android:enabled="false"/> <RadioButton android:id="@+id/remember_password" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/login_button" android:layout_marginTop="40dp" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:text="Remember Password" android:textSize="12dp" android:checked="false"/> </RelativeLayout> |
Login Android Example
MainActivity.kt
In MainActivity.kt file first define the toolbar above onCreate method.
1 |
private lateinit var toolbar: Toolbar |
Initialize the toolbar in onCreate method and set the default icons for our Email and Password fields.
1 2 3 4 5 |
toolbar = findViewById(R.id.toolbar_login) setSupportActionBar(toolbar) email.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.message, 0, 0, 0) password.setCompoundDrawablesRelativeWithIntrinsicBounds(Password, 0, 0, 0) |
Note: email and password are the ids of our EditText in XML and message and password are the names of vector icons we created in the beginning.
Now what we are going to do here is that our Text fields icons will change their color if the Text fields are not empty. If they have some text the icons will appear blue otherwise for the empty Text field it’s icon color will be transparent. For achieving this we will apply addTextChangedListener with TextWatcher on both of our EditText. It has three methods.
1- beforeTextChanged.
2- onTextChanged.
3- afterTextChanged.
In our case we are dealing with afterTextChanged method. We apply addTextChangedListener with TextWatcher on our email EditText like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
email.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { } override fun afterTextChanged(s: Editable) { if (s.length != 0) { var drawable = resources.getDrawable(R.drawable.message) //Your drawable image drawable = DrawableCompat.wrap(drawable!!) DrawableCompat.setTint(drawable, resources.getColor(R.color.colordarkblue)) // Set whatever color you want DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_IN) email.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null) email.setCompoundDrawablesWithIntrinsicBounds(resources.getDrawable(R.drawable.message), null, resources.getDrawable(R.drawable.cancel), null) } else if (s.length == 0) { email.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.message, 0, 0, 0) var drawable = resources.getDrawable(R.drawable.message) //Your drawable image drawable = DrawableCompat.wrap(drawable!!) DrawableCompat.setTint(drawable, resources.getColor(R.color.colorDefault)) // Set whatever color you want DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_IN) email.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null) email.setCompoundDrawablesWithIntrinsicBounds( resources.getDrawable(R.drawable.message), null, null, null ) } } }) |
For our password EditText we apply addTextChangedListener with TextWatcher like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
password.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { } override fun afterTextChanged(s: Editable) { if (s.length != 0) { var drawable = resources.getDrawable(R.drawable.password) //Your drawable image drawable = DrawableCompat.wrap(drawable!!) DrawableCompat.setTint(drawable, resources.getColor(R.color.colordarkblue)) // Set whatever color you want DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_IN) password.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null) password.setCompoundDrawablesWithIntrinsicBounds(resources.getDrawable(R.drawable.password), null, resources.getDrawable(R.drawable.cancel), null) } else if (s.length == 0) { password.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.password, 0, 0, 0) var drawable = resources.getDrawable(R.drawable.password) //Your drawable image drawable = DrawableCompat.wrap(drawable!!) DrawableCompat.setTint(drawable, resources.getColor(R.color.colorDefault)) // Set whatever color you want DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_IN) password.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null) password.setCompoundDrawablesWithIntrinsicBounds(resources.getDrawable(R.drawable.password), null, null, null ) } } }) |
Now we can see that after the above code whenever a user enters something in any Text field the icon color changes. Also a small “cancel” image appears on the right end of the EditText. Now will code for that “cancel” icon so that whenever the user presses that icon it will clear the Text box. This is how you can do that with the help of setOnTouchListener . In case of our email Text field like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
email.setOnTouchListener(View.OnTouchListener { v, event -> if (event.action == MotionEvent.ACTION_DOWN) { if (email.getCompoundDrawables().get(2) != null) { if (event.x >= email.getRight() - email.getLeft() - email.getCompoundDrawables().get(2).getBounds().width()) { if (email.getText().toString() != "") { email.setText("") } } } } false }) |
For our password Text field. Like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
password.setOnTouchListener(View.OnTouchListener { v, event -> if (event.action == MotionEvent.ACTION_DOWN) { if (password.getCompoundDrawables().get(2) != null) { if (event.x >= password() - password() - password.getCompoundDrawables().get(2).getBounds().width() ) { if (password.getText().toString() != "") { password("") } } } } false }) |
Radio Button
Now, we have a radio button in our activity_main.xml file. Here it doesn’t do anything because of that we put a simple code to check and uncheck the radio button when pressed. This is how to do that.
1 2 3 4 5 6 7 8 9 10 11 12 |
remember_password.setOnClickListener(View.OnClickListener { if (!(remember_password.isSelected)) { remember_password.isChecked = true remember_password.isSelected = true } else { remember_password.isChecked = false remember_password.isSelected = false } }) |
Note: remember_password is the id of our radio button in XML
If you notice we have used TextWatcher before to change the colors of our icons if the fields are empty/not empty. We need TextWatcher again but this time as a value because we have to change the color of the Button if any of the Text field is empty. We will do it outside our onCreate method like this.
TextWatcher as val
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
private val loginTextWatcher: TextWatcher = object : TextWatcher { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { } override fun afterTextChanged(s: Editable) { val mUsername: String = email.getText().toString().trim() val mPassword: String = password.getText().toString().trim() val t = !mUsername.isEmpty() && !mPassword.isEmpty() if (t) { login_button.setBackgroundResource(R.color.colordarkblue) } else { login_button.setBackgroundResource(R.color.colorwhiteblueshade) } } } |
After that, add this TextWatcher value ( loginTextWatcher ) with addTextChangedListener method for both EditText inside onCreate method like this.
1 2 |
email.addTextChangedListener(loginTextWatcher) password.addTextChangedListener(loginTextWatcher) |
Finally, when the app starts its obvious that our EditText are empty. Because of this apply a condition in our onStart method. It will display our Button as not enabled when the app starts. Override the onStart method like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
override fun onStart() { super.onStart() val mUsername: String = email.getText().toString().trim() val mPassword: String = password.getText().toString().trim() val t = !mUsername.isEmpty() && !mPassword.isEmpty() if (t) { login_button.setBackgroundResource(R.color.colordarkblue) } else { login_button.setBackgroundResource(R.color.colorwhiteblueshade) } } |
Our complete final MainActivity.kt file is like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
package com.example.loginapp import android.graphics.PorterDuff import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.text.Editable import android.text.TextWatcher import android.view.MotionEvent import android.view.View import androidx.appcompat.widget.Toolbar import androidx.core.graphics.drawable.DrawableCompat import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { private lateinit var toolbar: Toolbar override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) toolbar = findViewById(R.id.toolbar_login) setSupportActionBar(toolbar) email.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.message, 0, 0, 0) password.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.password, 0, 0, 0) email.addTextChangedListener(loginTextWatcher) password.addTextChangedListener(loginTextWatcher) email.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { } override fun afterTextChanged(s: Editable) { if (s.length != 0) { var drawable = resources.getDrawable(R.drawable.message) //Your drawable image drawable = DrawableCompat.wrap(drawable!!) DrawableCompat.setTint(drawable, resources.getColor(R.color.colordarkblue)) // Set whatever color you want DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_IN) email.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null) email.setCompoundDrawablesWithIntrinsicBounds(resources.getDrawable(R.drawable.message), null, resources.getDrawable(R.drawable.cancel), null) } else if (s.length == 0) { email.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.message, 0, 0, 0) var drawable = resources.getDrawable(R.drawable.message) //Your drawable image drawable = DrawableCompat.wrap(drawable!!) DrawableCompat.setTint(drawable, resources.getColor(R.color.colorDefault)) // Set whatever color you want DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_IN) email.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null) email.setCompoundDrawablesWithIntrinsicBounds( resources.getDrawable(R.drawable.message), null, null, null ) } } }) password.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { } override fun afterTextChanged(s: Editable) { if (s.length != 0) { var drawable = resources.getDrawable(R.drawable.password) //Your drawable image drawable = DrawableCompat.wrap(drawable!!) DrawableCompat.setTint(drawable, resources.getColor(R.color.colordarkblue)) // Set whatever color you want DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_IN) password.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null) password.setCompoundDrawablesWithIntrinsicBounds(resources.getDrawable(R.drawable.password), null, resources.getDrawable(R.drawable.cancel), null) } else if (s.length == 0) { password.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.password, 0, 0, 0) var drawable = resources.getDrawable(R.drawable.password) //Your drawable image drawable = DrawableCompat.wrap(drawable!!) DrawableCompat.setTint(drawable, resources.getColor(R.color.colorDefault)) // Set whatever color you want DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_IN) password.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null) password.setCompoundDrawablesWithIntrinsicBounds(resources.getDrawable(R.drawable.password), null, null, null ) } } }) email.setOnTouchListener(View.OnTouchListener { v, event -> if (event.action == MotionEvent.ACTION_DOWN) { if (email.getCompoundDrawables().get(2) != null) { if (event.x >= email.getRight() - email.getLeft() - email.getCompoundDrawables().get(2).getBounds().width()) { if (email.getText().toString() != "") { email.setText("") } } } } false }) password.setOnTouchListener(View.OnTouchListener { v, event -> if (event.action == MotionEvent.ACTION_DOWN) { if (password.getCompoundDrawables().get(2) != null) { if (event.x >= password.getRight() - password.getLeft() - password.getCompoundDrawables().get(2).getBounds().width() ) { if (password.getText().toString() != "") { password.setText("") } } } } false }) remember_password.setOnClickListener(View.OnClickListener { if (!(remember_password.isSelected)) { remember_password.isChecked = true remember_password.isSelected = true } else { remember_password.isChecked = false remember_password.isSelected = false } }) } private val loginTextWatcher: TextWatcher = object : TextWatcher { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { } override fun afterTextChanged(s: Editable) { val mUsername: String = email.getText().toString().trim() val mPassword: String = password.getText().toString().trim() val t = !mUsername.isEmpty() && !mPassword.isEmpty() if (t) { login_button.setBackgroundResource(R.color.colordarkblue) } else { login_button.setBackgroundResource(R.color.colorwhiteblueshade) } } } override fun onStart() { super.onStart() val mUsername: String = email.getText().toString().trim() val mPassword: String = password.getText().toString().trim() val t = !mUsername.isEmpty() && !mPassword.isEmpty() if (t) { login_button.setBackgroundResource(R.color.colordarkblue) } else { login_button.setBackgroundResource(R.color.colorwhiteblueshade) } } } |
So now here we complete our code. And I hope that you like this simple but beautiful Kotlin Login Screen for your android applications. Still if you’re facing issues in understanding Android Kotlin Login Example then ask in comments section. Have fun 🙂
OUTPUT




People Also Read:
Android Custom Toolbar In Kotlin
Enable or Disable Wifi In Android Programmatically In Kotlin
Kotlin Text To Speech Working Example
How To Check Internet Connection in Android Programmatically