Android[Kotlin] Login and Register with SQLite Database Tutorial
In software applications, it is mostly required to store users and app data locally. Android SDK provides several API’s for developers to save user and app data, So SQLite is one of the ways of storing data. For many applications, SQLite is the app’s backbone whether it’s used directly or via some third-party wrapper. In this tutorial, we will write code in Kotlin and also see how to use SQLite in our app directly.
What is SQLite?
SQLite is a lightweight database which comes with android. It is an Open-Source embedded SQL database engine. This provides relational database management structure for storing user-defined records in the form of tables.
Key point to understand regarding SQLite :-
– SQLite is RDBMS (Relational Database Management System)
– SQLite is written in C programming language
– SQLite is embedded within the Android Operating System, so you don’t need anything external on Android to use SQLite
– To manipulate data (insert, update, delete) in SQLite database – we’ll use SQL (Structured Query Language)
Let’s Get it Working
In this tutorial, we are going to learn how to use SQLite. To really understand the usage of SQLite we will create an app using Kotlin. The App contains simple Login form, Registration form, and a listing of a registered user. This app shows how SQLite database operations are performed. I assume that you have created a new android project. Source Code is available on GitHub.
Step 1) Update build.gradle file.
Before you can use Material Design in your projects you need to add the following compile line to your Gradle dependencies block in your build.gradle file and rebuilt the project .
dependencies { compile 'com.android.support:appcompat-v7:23.4.0' compile 'com.android.support:design:23.4.0' compile 'com.android.support:cardview-v7:23.4.0' }
Step 2) Update strings.xml.
Add the below string values to the string.xml located in res ⇒ values ⇒ strings.xml.
<resources> <string name="app_name">Login Register</string> <string name="text_accounts">All Accounts</string> <string name="hint_name">Name</string> <string name="hint_email">Email</string> <string name="hint_password">Password</string> <string name="hint_confirm_password">Confirm Password</string> <string name="text_login">Login</string> <string name="text_register">Register</string> <string name="error_message_name">Enter Full Name</string> <string name="error_message_email">Enter Valid Email</string> <string name="error_message_age">Enter Age</string> <string name="error_message_password">Enter Password</string> <string name="success_message">Registration Successful</string> <string name="text_not_member">No account yet? Create one</string> <string name="text_already_member">Already a member? Login</string> <string name="error_email_exists">Email Already Exists</string> <string name="error_password_match">Password Does Not Matches</string> <string name="error_valid_email_password">Wrong Email or Password</string> <string name="action_settings">Settings</string> <string name="text_hello">Hello,</string> <string name="text_title">Android Tutorials Hub</string> </resources>
Step 3) Update colors.xml.
Add the below color values to the colors.xml located in res ⇒ values ⇒ colors.xml.
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#51d8c7</color> <color name="colorPrimaryDark">#51d8c7</color> <color name="colorAccent">#FFFFFF</color> <color name="colorBackground">#413e4f</color> <color name="colorText">#FFFFFF</color> <color name="colorTextHint">#51d8c7</color> </resources>
Step 4) Update styles.xml.
Add the below style values to the styles.xml located in res ⇒ values ⇒ styles.xml.
<resources> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="android:textColor">@color/colorText</item> <item name="android:textColorHint">@color/colorText</item> <item name="colorControlNormal">@color/colorText</item> <item name="colorControlActivated">@color/colorText</item> </style> </resources>
Step 5) Add Logo Image.
Download the below logo image and add it to the drawable folder located in res ⇒ drawable.
Step 6) Create User data class.
Create a new package named modal and create a Kotlin file/class named User to maintain single contact as an object.
package com.androidtutorialshub.loginregisterkotlin.model // model class data class User(val id: Int = -1, val name: String, val email: String, val password: String)
Step 7) Create DatabaseHelper class.
Create a new package named sql and create Kotlin class named DatabaseHelper. Extend this class with SQLiteOpenHelper to manage database creation and version management. I have also written some method to manipulate data in database.
Methods and functionality
– addUser :- add user to database.
– getAllUser :- fetch users data from database.
– updateUser :- update user in database on the basis of user id.
– deleteUser :- delete user from database on the basis of user id.
– checkUser :- check whether user exists in database.
package com.androidtutorialshub.loginregisterkotlin.sql import android.content.ContentValues import android.content.Context import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper import com.androidtutorialshub.loginregisterkotlin.model.User import java.util.* class DatabaseHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) { // create table sql query private val CREATE_USER_TABLE = ("CREATE TABLE " + TABLE_USER + "(" + COLUMN_USER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_USER_NAME + " TEXT," + COLUMN_USER_EMAIL + " TEXT," + COLUMN_USER_PASSWORD + " TEXT" + ")") // drop table sql query private val DROP_USER_TABLE = "DROP TABLE IF EXISTS $TABLE_USER" override fun onCreate(db: SQLiteDatabase) { db.execSQL(CREATE_USER_TABLE) } override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { //Drop User Table if exist db.execSQL(DROP_USER_TABLE) // Create tables again onCreate(db) } /** * This method is to fetch all user and return the list of user records * * @return list */ fun getAllUser(): List { // array of columns to fetch val columns = arrayOf(COLUMN_USER_ID, COLUMN_USER_EMAIL, COLUMN_USER_NAME, COLUMN_USER_PASSWORD) // sorting orders val sortOrder = "$COLUMN_USER_NAME ASC" val userList = ArrayList() val db = this.readableDatabase // query the user table val cursor = db.query(TABLE_USER, //Table to query columns, //columns to return null, //columns for the WHERE clause null, //The values for the WHERE clause null, //group the rows null, //filter by row groups sortOrder) //The sort order if (cursor.moveToFirst()) { do { val user = User(id = cursor.getString(cursor.getColumnIndex(COLUMN_USER_ID)).toInt(), name = cursor.getString(cursor.getColumnIndex(COLUMN_USER_NAME)), email = cursor.getString(cursor.getColumnIndex(COLUMN_USER_EMAIL)), password = cursor.getString(cursor.getColumnIndex(COLUMN_USER_PASSWORD))) userList.add(user) } while (cursor.moveToNext()) } cursor.close() db.close() return userList } /** * This method is to create user record * * @param user */ fun addUser(user: User) { val db = this.writableDatabase val values = ContentValues() values.put(COLUMN_USER_NAME, user.name) values.put(COLUMN_USER_EMAIL, user.email) values.put(COLUMN_USER_PASSWORD, user.password) // Inserting Row db.insert(TABLE_USER, null, values) db.close() } /** * This method to update user record * * @param user */ fun updateUser(user: User) { val db = this.writableDatabase val values = ContentValues() values.put(COLUMN_USER_NAME, user.name) values.put(COLUMN_USER_EMAIL, user.email) values.put(COLUMN_USER_PASSWORD, user.password) // updating row db.update(TABLE_USER, values, "$COLUMN_USER_ID = ?", arrayOf(user.id.toString())) db.close() } /** * This method is to delete user record * * @param user */ fun deleteUser(user: User) { val db = this.writableDatabase // delete user record by id db.delete(TABLE_USER, "$COLUMN_USER_ID = ?", arrayOf(user.id.toString())) db.close() } /** * This method to check user exist or not * * @param email * @return true/false */ fun checkUser(email: String): Boolean { // array of columns to fetch val columns = arrayOf(COLUMN_USER_ID) val db = this.readableDatabase // selection criteria val selection = "$COLUMN_USER_EMAIL = ?" // selection argument val selectionArgs = arrayOf(email) // query user table with condition /** * Here query function is used to fetch records from user table this function works like we use sql query. * SQL query equivalent to this query function is * SELECT user_id FROM user WHERE user_email = 'jack@androidtutorialshub.com'; */ val cursor = db.query(TABLE_USER, //Table to query columns, //columns to return selection, //columns for the WHERE clause selectionArgs, //The values for the WHERE clause null, //group the rows null, //filter by row groups null) //The sort order val cursorCount = cursor.count cursor.close() db.close() if (cursorCount > 0) { return true } return false } /** * This method to check user exist or not * * @param email * @param password * @return true/false */ fun checkUser(email: String, password: String): Boolean { // array of columns to fetch val columns = arrayOf(COLUMN_USER_ID) val db = this.readableDatabase // selection criteria val selection = "$COLUMN_USER_EMAIL = ? AND $COLUMN_USER_PASSWORD = ?" // selection arguments val selectionArgs = arrayOf(email, password) // query user table with conditions /** * Here query function is used to fetch records from user table this function works like we use sql query. * SQL query equivalent to this query function is * SELECT user_id FROM user WHERE user_email = 'jack@androidtutorialshub.com' AND user_password = 'qwerty'; */ val cursor = db.query(TABLE_USER, //Table to query columns, //columns to return selection, //columns for the WHERE clause selectionArgs, //The values for the WHERE clause null, //group the rows null, //filter by row groups null) //The sort order val cursorCount = cursor.count cursor.close() db.close() if (cursorCount > 0) return true return false } companion object { // Database Version private val DATABASE_VERSION = 1 // Database Name private val DATABASE_NAME = "UserManager.db" // User table name private val TABLE_USER = "user" // User Table Columns names private val COLUMN_USER_ID = "user_id" private val COLUMN_USER_NAME = "user_name" private val COLUMN_USER_EMAIL = "user_email" private val COLUMN_USER_PASSWORD = "user_password" } }
Step 8) Create activity_login.xml.
Now create a layout file for the LoginActivity.kt i.e activity_login.xml and add the below code in your layout file. The code will create a simple login form containing a logo on the top, 2 input fields email and password, login button, and registration screen navigation link.
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nestedScrollView" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorBackground" android:paddingBottom="20dp" android:paddingLeft="20dp" android:paddingRight="20dp" android:paddingTop="20dp" tools:context=".activities.LoginActivity"> <android.support.v7.widget.LinearLayoutCompat android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.AppCompatImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="40dp" android:src="@drawable/logo" /> <android.support.design.widget.TextInputLayout android:id="@+id/textInputLayoutEmail" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="40dp"> <android.support.design.widget.TextInputEditText android:id="@+id/textInputEditTextEmail" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/hint_email" android:inputType="text" android:maxLines="1" android:textColor="@android:color/white" /> </android.support.design.widget.TextInputLayout> <android.support.design.widget.TextInputLayout android:id="@+id/textInputLayoutPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp"> <android.support.design.widget.TextInputEditText android:id="@+id/textInputEditTextPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/hint_password" android:inputType="textPassword" android:maxLines="1" android:textColor="@android:color/white" /> </android.support.design.widget.TextInputLayout> <android.support.v7.widget.AppCompatButton android:id="@+id/appCompatButtonLogin" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:background="@color/colorTextHint" android:text="@string/text_login" /> <android.support.v7.widget.AppCompatTextView android:id="@+id/textViewLinkRegister" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:gravity="center" android:text="@string/text_not_member" android:textSize="16dp" /> </android.support.v7.widget.LinearLayoutCompat> </android.support.v4.widget.NestedScrollView>
activity_login.xml would result a screen like this:
Step 8) Create InputValidation class.
Create a package named helpers and create a Kotlin class in it named InputValidation.kt and add below code in it. The code will create validation methods for input field. Validation like empty input, valid email and etc.
package com.androidtutorialshub.loginregisterkotlin.helpers import android.app.Activity import android.content.Context import android.support.design.widget.TextInputEditText import android.support.design.widget.TextInputLayout import android.view.View import android.view.WindowManager import android.view.inputmethod.InputMethodManager class InputValidation /** * constructor * * @param context */ (private val context: Context) { /** * method to check InputEditText filled . * * @param textInputEditText * @param textInputLayout * @param message * @return */ fun isInputEditTextFilled(textInputEditText: TextInputEditText, textInputLayout: TextInputLayout, message: String): Boolean { val value = textInputEditText.text.toString().trim() if (value.isEmpty()) { textInputLayout.error = message hideKeyboardFrom(textInputEditText) return false } else { textInputLayout.isErrorEnabled = false } return true } /** * method to check InputEditText has valid email . * * @param textInputEditText * @param textInputLayout * @param message * @return */ fun isInputEditTextEmail(textInputEditText: TextInputEditText, textInputLayout: TextInputLayout, message: String): Boolean { val value = textInputEditText.text.toString().trim() if (value.isEmpty() || !android.util.Patterns.EMAIL_ADDRESS.matcher(value).matches()) { textInputLayout.error = message hideKeyboardFrom(textInputEditText) return false } else { textInputLayout.isErrorEnabled = false } return true } /** * method to check both InputEditText value matches. * * @param textInputEditText1 * @param textInputEditText2 * @param textInputLayout * @param message * @return */ fun isInputEditTextMatches(textInputEditText1: TextInputEditText, textInputEditText2: TextInputEditText, textInputLayout: TextInputLayout, message: String): Boolean { val value1 = textInputEditText1.text.toString().trim() val value2 = textInputEditText2.text.toString().trim() if (!value1.contentEquals(value2)) { textInputLayout.error = message hideKeyboardFrom(textInputEditText2) return false } else { textInputLayout.isErrorEnabled = false } return true } /** * method to Hide keyboard * * @param view */ private fun hideKeyboardFrom(view: View) { val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager imm.hideSoftInputFromWindow(view.windowToken, WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) } }
Step 9) Create LoginActivity class.
Now create a package named activities and create a kotlin class named LoginActivity and add below code. Here i have written the code to validate the input fields Email and Password using the InputValidation class which i described above. Also code for navigation to registration screen on the click of registration link and to user list screen after click on login button if credentials are valid.
package com.androidtutorialshub.loginregisterkotlin.activities import android.content.Intent import android.os.Bundle import android.support.design.widget.Snackbar import android.support.design.widget.TextInputEditText import android.support.design.widget.TextInputLayout import android.support.v4.widget.NestedScrollView import android.support.v7.app.AppCompatActivity import android.support.v7.widget.AppCompatButton import android.support.v7.widget.AppCompatTextView import android.view.View import com.androidtutorialshub.loginregisterkotlin.R import com.androidtutorialshub.loginregisterkotlin.helpers.InputValidation import com.androidtutorialshub.loginregisterkotlin.sql.DatabaseHelper class LoginActivity : AppCompatActivity(), View.OnClickListener { private val activity = this@LoginActivity private lateinit var nestedScrollView: NestedScrollView private lateinit var textInputLayoutEmail: TextInputLayout private lateinit var textInputLayoutPassword: TextInputLayout private lateinit var textInputEditTextEmail: TextInputEditText private lateinit var textInputEditTextPassword: TextInputEditText private lateinit var appCompatButtonLogin: AppCompatButton private lateinit var textViewLinkRegister: AppCompatTextView private lateinit var inputValidation: InputValidation private lateinit var databaseHelper: DatabaseHelper override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_login) // hiding the action bar supportActionBar!!.hide() // initializing the views initViews() // initializing the listeners initListeners() // initializing the objects initObjects() } /** * This method is to initialize views */ private fun initViews() { nestedScrollView = findViewById(R.id.nestedScrollView) as NestedScrollView textInputLayoutEmail = findViewById(R.id.textInputLayoutEmail) as TextInputLayout textInputLayoutPassword = findViewById(R.id.textInputLayoutPassword) as TextInputLayout textInputEditTextEmail = findViewById(R.id.textInputEditTextEmail) as TextInputEditText textInputEditTextPassword = findViewById(R.id.textInputEditTextPassword) as TextInputEditText appCompatButtonLogin = findViewById(R.id.appCompatButtonLogin) as AppCompatButton textViewLinkRegister = findViewById(R.id.textViewLinkRegister) as AppCompatTextView } /** * This method is to initialize listeners */ private fun initListeners() { appCompatButtonLogin!!.setOnClickListener(this) textViewLinkRegister!!.setOnClickListener(this) } /** * This method is to initialize objects to be used */ private fun initObjects() { databaseHelper = DatabaseHelper(activity) inputValidation = InputValidation(activity) } /** * This implemented method is to listen the click on view * * @param v */ override fun onClick(v: View) { when (v.id) { R.id.appCompatButtonLogin -> verifyFromSQLite() R.id.textViewLinkRegister -> { // Navigate to RegisterActivity val intentRegister = Intent(applicationContext, RegisterActivity::class.java) startActivity(intentRegister) } } } /** * This method is to validate the input text fields and verify login credentials from SQLite */ private fun verifyFromSQLite() { if (!inputValidation!!.isInputEditTextFilled(textInputEditTextEmail!!, textInputLayoutEmail!!, getString(R.string.error_message_email))) { return } if (!inputValidation!!.isInputEditTextEmail(textInputEditTextEmail!!, textInputLayoutEmail!!, getString(R.string.error_message_email))) { return } if (!inputValidation!!.isInputEditTextFilled(textInputEditTextPassword!!, textInputLayoutPassword!!, getString(R.string.error_message_email))) { return } if (databaseHelper!!.checkUser(textInputEditTextEmail!!.text.toString().trim { it <= ' ' }, textInputEditTextPassword!!.text.toString().trim { it <= ' ' })) { val accountsIntent = Intent(activity, UsersListActivity::class.java) accountsIntent.putExtra("EMAIL", textInputEditTextEmail!!.text.toString().trim { it <= ' ' }) emptyInputEditText() startActivity(accountsIntent) } else { // Snack Bar to show success message that record is wrong Snackbar.make(nestedScrollView!!, getString(R.string.error_valid_email_password), Snackbar.LENGTH_LONG).show() } } /** * This method is to empty all input edit text */ private fun emptyInputEditText() { textInputEditTextEmail!!.text = null textInputEditTextPassword!!.text = null } }
The Screen below shows the login form with input validation display the error message if values entered in input fields are not valid.
The Screen below shows the login form with input validation display the snack bar with message if values entered in input fields are not validated from SQLite database.
Step 10) Create activity_register.xml.
Now create a layout file for the RegisterActivity.kt i.e activity_register.xml and add the below code in your layout file. The code will create a simple registration form containing a logo on the top, 4 input fields name, email, password, and confirm password, register button, and login screen navigation link.
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nestedScrollView" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorBackground" android:paddingBottom="20dp" android:paddingLeft="20dp" android:paddingRight="20dp" android:paddingTop="20dp" tools:context=".activities.LoginActivity"> <android.support.v7.widget.LinearLayoutCompat android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.AppCompatImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="40dp" android:src="@drawable/logo" /> <android.support.design.widget.TextInputLayout android:id="@+id/textInputLayoutName" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="40dp"> <android.support.design.widget.TextInputEditText android:id="@+id/textInputEditTextName" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/hint_name" android:inputType="text" android:maxLines="1" android:textColor="@android:color/white" /> </android.support.design.widget.TextInputLayout> <android.support.design.widget.TextInputLayout android:id="@+id/textInputLayoutEmail" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp"> <android.support.design.widget.TextInputEditText android:id="@+id/textInputEditTextEmail" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/hint_email" android:inputType="text" android:maxLines="1" android:textColor="@android:color/white" /> </android.support.design.widget.TextInputLayout> <android.support.design.widget.TextInputLayout android:id="@+id/textInputLayoutPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp"> <android.support.design.widget.TextInputEditText android:id="@+id/textInputEditTextPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/hint_password" android:inputType="textPassword" android:maxLines="1" android:textColor="@android:color/white" /> </android.support.design.widget.TextInputLayout> <android.support.design.widget.TextInputLayout android:id="@+id/textInputLayoutConfirmPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp"> <android.support.design.widget.TextInputEditText android:id="@+id/textInputEditTextConfirmPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/hint_confirm_password" android:inputType="textPassword" android:maxLines="1" android:textColor="@android:color/white" /> </android.support.design.widget.TextInputLayout> <android.support.v7.widget.AppCompatButton android:id="@+id/appCompatButtonRegister" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:background="@color/colorTextHint" android:text="@string/text_register" /> <android.support.v7.widget.AppCompatTextView android:id="@+id/appCompatTextViewLoginLink" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:gravity="center" android:text="Already a member? Login" android:textSize="16dp" /> </android.support.v7.widget.LinearLayoutCompat> </android.support.v4.widget.NestedScrollView>
activity_register.xml would result a screen like this:
Step 11) Create RegisterActivity class.
Now create a package named activities and create a kotlin class named RegisterActivity and add below code. Here I have written the code to validate the input fields Name, Email, Password, and Confirm Password using the InputValidation class which I described above. Also, code for navigation to the login screen on the click of the login link and shows a snack bar with a success message for registration.
package com.androidtutorialshub.loginregisterkotlin.activities import android.os.Bundle import android.support.design.widget.Snackbar import android.support.design.widget.TextInputEditText import android.support.design.widget.TextInputLayout import android.support.v4.widget.NestedScrollView import android.support.v7.app.AppCompatActivity import android.support.v7.widget.AppCompatButton import android.support.v7.widget.AppCompatTextView import android.view.View import com.androidtutorialshub.loginregisterkotlin.R import com.androidtutorialshub.loginregisterkotlin.helpers.InputValidation import com.androidtutorialshub.loginregisterkotlin.model.User import com.androidtutorialshub.loginregisterkotlin.sql.DatabaseHelper class RegisterActivity : AppCompatActivity(), View.OnClickListener { private val activity = this@RegisterActivity private lateinit var nestedScrollView: NestedScrollView private lateinit var textInputLayoutName: TextInputLayout private lateinit var textInputLayoutEmail: TextInputLayout private lateinit var textInputLayoutPassword: TextInputLayout private lateinit var textInputLayoutConfirmPassword: TextInputLayout private lateinit var textInputEditTextName: TextInputEditText private lateinit var textInputEditTextEmail: TextInputEditText private lateinit var textInputEditTextPassword: TextInputEditText private lateinit var textInputEditTextConfirmPassword: TextInputEditText private lateinit var appCompatButtonRegister: AppCompatButton private lateinit var appCompatTextViewLoginLink: AppCompatTextView private lateinit var inputValidation: InputValidation private lateinit var databaseHelper: DatabaseHelper override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_register) // hiding the action bar supportActionBar!!.hide() // initializing the views initViews() // initializing the listeners initListeners() // initializing the objects initObjects() } /** * This method is to initialize views */ private fun initViews() { nestedScrollView = findViewById(R.id.nestedScrollView) as NestedScrollView textInputLayoutName = findViewById(R.id.textInputLayoutName) as TextInputLayout textInputLayoutEmail = findViewById(R.id.textInputLayoutEmail) as TextInputLayout textInputLayoutPassword = findViewById(R.id.textInputLayoutPassword) as TextInputLayout textInputLayoutConfirmPassword = findViewById(R.id.textInputLayoutConfirmPassword) as TextInputLayout textInputEditTextName = findViewById(R.id.textInputEditTextName) as TextInputEditText textInputEditTextEmail = findViewById(R.id.textInputEditTextEmail) as TextInputEditText textInputEditTextPassword = findViewById(R.id.textInputEditTextPassword) as TextInputEditText textInputEditTextConfirmPassword = findViewById(R.id.textInputEditTextConfirmPassword) as TextInputEditText appCompatButtonRegister = findViewById(R.id.appCompatButtonRegister) as AppCompatButton appCompatTextViewLoginLink = findViewById(R.id.appCompatTextViewLoginLink) as AppCompatTextView } /** * This method is to initialize listeners */ private fun initListeners() { appCompatButtonRegister!!.setOnClickListener(this) appCompatTextViewLoginLink!!.setOnClickListener(this) } /** * This method is to initialize objects to be used */ private fun initObjects() { inputValidation = InputValidation(activity) databaseHelper = DatabaseHelper(activity) } /** * This implemented method is to listen the click on view * * @param v */ override fun onClick(v: View) { when (v.id) { R.id.appCompatButtonRegister -> postDataToSQLite() R.id.appCompatTextViewLoginLink -> finish() } } /** * This method is to validate the input text fields and post data to SQLite */ private fun postDataToSQLite() { if (!inputValidation!!.isInputEditTextFilled(textInputEditTextName, textInputLayoutName, getString(R.string.error_message_name))) { return } if (!inputValidation!!.isInputEditTextFilled(textInputEditTextEmail, textInputLayoutEmail, getString(R.string.error_message_email))) { return } if (!inputValidation!!.isInputEditTextEmail(textInputEditTextEmail, textInputLayoutEmail, getString(R.string.error_message_email))) { return } if (!inputValidation!!.isInputEditTextFilled(textInputEditTextPassword, textInputLayoutPassword, getString(R.string.error_message_password))) { return } if (!inputValidation!!.isInputEditTextMatches(textInputEditTextPassword, textInputEditTextConfirmPassword, textInputLayoutConfirmPassword, getString(R.string.error_password_match))) { return } if (!databaseHelper!!.checkUser(textInputEditTextEmail!!.text.toString().trim())) { var user = User(name = textInputEditTextName!!.text.toString().trim(), email = textInputEditTextEmail!!.text.toString().trim(), password = textInputEditTextPassword!!.text.toString().trim()) databaseHelper!!.addUser(user) // Snack Bar to show success message that record saved successfully Snackbar.make(nestedScrollView!!, getString(R.string.success_message), Snackbar.LENGTH_LONG).show() emptyInputEditText() } else { // Snack Bar to show error message that record already exists Snackbar.make(nestedScrollView!!, getString(R.string.error_email_exists), Snackbar.LENGTH_LONG).show() } } /** * This method is to empty all input edit text */ private fun emptyInputEditText() { textInputEditTextName!!.text = null textInputEditTextEmail!!.text = null textInputEditTextPassword!!.text = null textInputEditTextConfirmPassword!!.text = null } }
The Screen below shows the register form with input validation display the error message if values entered in input fields are not valid.
The Screen below shows the filled register form with valid values.
The Screen below shows the register form display the snackbar with registration success message.
Step 12) Create activity_users_list.xml.
Now create a layout file for the UsersListActivity.kt i.e activity_users_list.xml and add the below code in your layout file. The code will create a simple view containing two views one view i.e LinearLayout shows the welcome message with email id of the logged-in user and other views i.e RecyclerView shows the list of registered users in the app.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.LinearLayoutCompat android:layout_width="match_parent" android:layout_height="150dp" android:background="@color/colorPrimary" android:gravity="center" android:orientation="vertical"> <android.support.v7.widget.AppCompatTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/text_title" android:textSize="20sp" /> <android.support.v7.widget.AppCompatTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="@string/text_hello" /> <android.support.v7.widget.AppCompatTextView android:id="@+id/textViewName" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </android.support.v7.widget.LinearLayoutCompat> <android.support.v7.widget.AppCompatTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingBottom="5dp" android:paddingLeft="16dp" android:paddingTop="5dp" android:text="@string/text_accounts" android:textColor="@android:color/black" /> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerViewUsers" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
activity_users_list.xml would result a screen like this:
Step 13) Writing the Adapter Class.
Now create a package named adapters and create a kotlin class named UsersRecyclerAdapter and add below code. Here onCreateViewHolder() method inflates item_user_recycler.xml. In onBindViewHolder() method the appropriate User data (name,email and password) set to each row.
package com.androidtutorialshub.loginregisterkotlin.adapters import android.support.v7.widget.AppCompatTextView import android.support.v7.widget.RecyclerView import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.androidtutorialshub.loginregisterkotlin.R import com.androidtutorialshub.loginregisterkotlin.model.User class UsersRecyclerAdapter(private val listUsers: List) : RecyclerView.Adapter() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder { // inflating recycler item view val itemView = LayoutInflater.from(parent.context) .inflate(R.layout.item_user_recycler, parent, false) return UserViewHolder(itemView) } override fun onBindViewHolder(holder: UserViewHolder, position: Int) { holder.textViewName.text = listUsers[position].name holder.textViewEmail.text = listUsers[position].email holder.textViewPassword.text = listUsers[position].password } override fun getItemCount(): Int { return listUsers.size } /** * ViewHolder class */ inner class UserViewHolder(view: View) : RecyclerView.ViewHolder(view) { var textViewName: AppCompatTextView var textViewEmail: AppCompatTextView var textViewPassword: AppCompatTextView init { textViewName = view.findViewById(R.id.textViewName) as AppCompatTextView textViewEmail = view.findViewById(R.id.textViewEmail) as AppCompatTextView textViewPassword = view.findViewById(R.id.textViewPassword) as AppCompatTextView } } }
item_user_recycler.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" card_view:cardCornerRadius="4dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <android.support.v7.widget.AppCompatTextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="2" android:text="@string/hint_name" android:textColor="@color/colorTextHint" /> <android.support.v7.widget.AppCompatTextView android:id="@+id/textViewName" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/hint_name" android:textColor="@android:color/darker_gray" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:orientation="horizontal"> <android.support.v7.widget.AppCompatTextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="2" android:text="@string/hint_email" android:textColor="@color/colorTextHint" /> <android.support.v7.widget.AppCompatTextView android:id="@+id/textViewEmail" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/hint_email" android:textColor="@android:color/darker_gray" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:orientation="horizontal"> <android.support.v7.widget.AppCompatTextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="2" android:text="@string/hint_password" android:textColor="@color/colorTextHint" /> <android.support.v7.widget.AppCompatTextView android:id="@+id/textViewPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/hint_password" android:textColor="@android:color/darker_gray" /> </LinearLayout> </LinearLayout> </android.support.v7.widget.CardView>
Step 14) Create UsersListActivity class.
Now create a package named activities and create a kotlin class named UsersListActivity and add below code. Here I have written the code to show the email id of the logged in user and the list of registered users.
package com.androidtutorialshub.loginregisterkotlin.activities import android.os.AsyncTask import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.support.v7.widget.AppCompatTextView import android.support.v7.widget.DefaultItemAnimator import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import android.view.View import com.androidtutorialshub.loginregisterkotlin.R import com.androidtutorialshub.loginregisterkotlin.adapters.UsersRecyclerAdapter import com.androidtutorialshub.loginregisterkotlin.model.User import com.androidtutorialshub.loginregisterkotlin.sql.DatabaseHelper class UsersListActivity : AppCompatActivity() { private val activity = this@UsersListActivity private lateinit var textViewName: AppCompatTextView private lateinit var recyclerViewUsers: RecyclerView private lateinit var listUsers: MutableList private lateinit var usersRecyclerAdapter: UsersRecyclerAdapter private lateinit var databaseHelper: DatabaseHelper override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_users_list) supportActionBar!!.title = "" initViews() initObjects() } /** * This method is to initialize views */ private fun initViews() { textViewName = findViewById(R.id.textViewName) as AppCompatTextView recyclerViewUsers = findViewById(R.id.recyclerViewUsers) as RecyclerView } /** * This method is to initialize objects to be used */ private fun initObjects() { listUsers = ArrayList() usersRecyclerAdapter = UsersRecyclerAdapter(listUsers) val mLayoutManager = LinearLayoutManager(applicationContext) recyclerViewUsers.layoutManager = mLayoutManager recyclerViewUsers.itemAnimator = DefaultItemAnimator() recyclerViewUsers.setHasFixedSize(true) recyclerViewUsers.adapter = usersRecyclerAdapter databaseHelper = DatabaseHelper(activity) val emailFromIntent = intent.getStringExtra("EMAIL") textViewName.text = emailFromIntent var getDataFromSQLite = GetDataFromSQLite() getDataFromSQLite.execute() } /** * This class is to fetch all user records from SQLite */ inner class GetDataFromSQLite : AsyncTask<Void, Void, List>() { override fun doInBackground(vararg p0: Void?): List { return databaseHelper.getAllUser() } override fun onPostExecute(result: List?) { super.onPostExecute(result) listUsers.clear() listUsers.addAll(result!!) } } }
The Screen below after user login shows the brand name, email id of logged in user and registered users list.
Step 15) Update AndroidManifest.xml.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.androidtutorialshub.loginregister"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".activities.LoginActivity" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".activities.RegisterActivity" android:screenOrientation="portrait" /> <activity android:name=".activities.UsersListActivity" android:screenOrientation="portrait" /> </application> </manifest>
Please feel free to comment as well as ask questions. And, yeah! If this post helps you please do share!
Enjoy Coding and Share Knowledge