Dauris Little
  • About
  • Blogging Lyf
  • Contact
  • Portfolio
“Never be limited by other people’s limited imaginations.” – Dr. Mae Jamison

QR Reader in Android w/ Kotlin

Wednesday, 15 September 2021 by Dauris

You may have noticed that QR codes are popping up all around and many of us have become accustomed to using these codes to quickly access information. As a developer know that qr codes are quick, easy, convenient, and alluring for users to scan. Within this read you will learn to implement a QR code scanner in Android Studio with very few steps.

Project Creation

Well of course you need somewhere to start so firing up your Android Studio it you haven’t already. Select the project you prefer to use but for this tutorial we are going to use the “Empty Activity” template just to keep it simple. (If you require more content on the different templates check out: Blah Blah)

NOTE: minimum SDK is 7.0

Adding Gradle Dependency and Manifest

Before we can access the class from ZXing we need to import the dependency to the module build.gradle file. (I always suggest using the latest stable version with that I suggest using the project structure when import dependencies) We also need to add permission to the AndroidMainfest.xml to access to the camera.

NOTE: If you are not familiar with using the Project Structure, please see blog regarding this feature in android studio.

// build.gradle
dependencies {

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.3.0'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'com.journeyapps:zxing-android-embedded:4.3.0' //added 
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
} 
// AndroidMainifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.programmingninja.qrreader">

    <uses-permission android:name="android.permission.CAMERA" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.QRReader">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Updating Layout

Now that we have completed the lightweight stuff lets begin by updating the activity_main.xml. We are going to keep the ConstraintLayout and add within it AppCompatTextView and AppCompatImageButton. 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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.AppCompatTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv_message"
        android:text="Tap Button Below to Begin Scanning!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.appcompat.widget.AppCompatImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/img_btn_qr"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_message"
        android:src="@drawable/ic_baseline_qr_code_scanner_24"/>
</androidx.constraintlayout.widget.ConstraintLayout> 

Finally Some Kotlin Writing

Within this class we need to use the ZXing IntentIntegrator to override the onActivityResult function. IntentIntegrator allows us to start the scanner with a few lines of code. The result will then appear in our Activity’s and if the user has not provided permission, yet they are present a message to provide access. After access is provided and user scans a code a new AlertDialog is present to perform action from the QR code itself. I will provide the code and blew the snippet you will be informed of everything is greater detail

package com.programmingninja.qrreader

import android.app.SearchManager
import android.content.DialogInterface
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.AppCompatButton
import androidx.appcompat.widget.AppCompatImageButton
import androidx.appcompat.widget.AppCompatTextView
import com.google.zxing.integration.android.IntentIntegrator

@Suppress("DEPRECATION")
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val msgTxt:AppCompatTextView = findViewById(R.id.tv_message)
        val imgBtn:AppCompatImageButton = findViewById(R.id.img_btn_qr)

        imgBtn.setOnClickListener {
            val intentIntegrator = IntentIntegrator(this)

            intentIntegrator.setDesiredBarcodeFormats(listOf(IntentIntegrator.QR_CODE))
            intentIntegrator.initiateScan()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        val res = IntentIntegrator.parseActivityResult(resultCode,data)

        if (res != null) {
            AlertDialog.Builder(this).setMessage("Would you like to go to ${res.contents}?")
                .setPositiveButton("Accept", DialogInterface.OnClickListener{
                    dialogInterface, i -> val intent = Intent(Intent.ACTION_WEB_SEARCH)
                    intent.putExtra(SearchManager.QUERY, res.contents)
                    startActivity(intent)
                })
                .setNegativeButton("Deny", DialogInterface.OnClickListener{ dialogInterface, i ->  })
                .create()
                .show()
        }
    }
}

Let’s first review the onCreate function, we are referencing the views in the layout, then we assign an OnClickListener to our AppCompatImageButton which then use an instance of IntentIntegrator which begin the scan.  We are settubg tge setDesiredBarcodeFormats function on the variable intentIntegrator. This function allows us to narrow down our barcode format to only focus. The ZXing IntentIntegrator class has support for several barcode formats, however for this tutorial we are going to focus on QR codes. Start the scan using the variable iIntegrator initiateScan function.

Now we create a function called onActivityResult and for this function to work we have to call the super.OnActivityResult function. In this function we create a variable called ‘res’ which holds the data collected from iIntegrator parseActivityResult function. Inside the function is a conditional statement to check if the scan is empty

Within the statement, we build an AlertDialog with a positive and negative button and each button have an action assigned to them. If the positive button is selected then an Intent will be used to start an internet search with QR code’s data but if the negative button is selected then user remains within the app.

Install, Test and Verify

If everything is implemented correctly, we can test the app, run it in the android studio and install it on a device. Now that the app installed, the app will open automatically and display the text and image button. when the user it will request permission to access the camera in your Setting. The camera reads the code and presents it in the AlertDialog a message that is stored in the qr code.

 

Dark Mode

android-tutorial (this link opens in a new window) by daurislittle (this link opens in a new window)

Android Tutorial beginner and advance

1 Subscriber 0 Watchers 0 Forks Check out this repository on GitHub.com (this link opens in a new window)

androidandroid developmentandroid permissionskotlinMobile Development
Read more
  • Published in Android, blog, Kotlin, Programming Languages, Tutorial
No Comments

Creating Advance Custom Snackbar w/ Kotlin

Monday, 28 June 2021 by Dauris

Ask 100 different developers about what they find most exciting about android development and you will get as many different responses. Personally, I find the customization of the various framework and design libraries. Consider it as such if there is something that doesn’t fit your needs within the development process that as a developer we create custom views without any issues. Within this post, we will be working on a custom Snackbar.

What is a Snackbar? Well simply enough a Snackbars provide lightweight feedback about an operation. They show a brief message at the bottom of the screen on mobile and lower left on larger devices. Snackbars appear above all other elements on screen and only one can be displayed at a time.

Though the Snackbar by default has a few customizable features, consider the fact that the default features may not match the application style. Fortunately, we can easily create a custom Snackbar by implementing just a few classes.  If you are unfamiliar with what a Snackbar is please review my previous post regarding the library. Be aware that it may be a little confusing at glance but fear not we will review it the most important part that is to highlight which are:

  • BottomTransientBottomBar which is the parent view
    •  ContentViewCallback
  • make() a factory method
    • find the parent view, inflate the custom view, and set additional properties 
  • customizable method

Custom View

It is assumed that you have already created/opened your current project within your IDE. Now we create a custom view that will be displayed at the bottom of the screen when called. This design will be the simplest form which contains an image and static message.

class CustomSnackbarView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : ConstraintLayout (context, attrs, defStyleAttr) {

    private val customImg : AppCompatImageView

    init {
        View.inflate(context, R.layout.view_custom_snackbar, this)
        clipToPadding = false
        this.customImg = findViewById(R.id.img_snack)
    }
}

this is accompanied by the following layout XML

<?xml version="1.0" encoding="utf-8"?>
<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">

    <androidx.appcompat.widget.AppCompatImageView
        android:layout_width="173dp"
        android:layout_height="173dp"
        android:id="@+id/img_snack"
        android:scaleType="centerInside"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:srcCompat="@drawable/pokeball" />

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:id="@+id/tv_snack"
        android:gravity="center"
        android:padding="16dp"
        android:text="You have caught another sir!"
        android:textColor="#28140c"
        android:background="@drawable/custom_snackbar_bg"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="@+id/img_snack"
        app:layout_constraintLeft_toRightOf="@+id/img_snack"
        app:layout_constraintStart_toEndOf="@+id/img_snack"
        app:layout_constraintTop_toTopOf="@+id/img_snack"
        app:layout_constraintVertical_bias="0.75" />
</merge>

Implementation of Custom View

Now the objective is to implement ContentViewCallback. The interface objective is to notify when the Snackbar starts appearing  and dismissing using animateContentIn() and animateContentOut()

class CustomSnackbarView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : ConstraintLayout (context, attrs, defStyleAttr), ContentViewCallback {

    private val customImg : AppCompatImageView

    init {
        View.inflate(context, R.layout.view_custom_snackbar, this)
        clipToPadding = false
        this.customImg = findViewById(R.id.img_snack)
    }

    override fun animateContentIn(delay: Int, duration: Int) {
        val scaleX = ObjectAnimator.ofFloat(customImg, View.SCALE_X, 0f, 1f)
        val scaleY = ObjectAnimator.ofFloat(customImg, View.SCALE_Y, 0f, 1f)
        AnimatorSet().apply {
            interpolator = OvershootInterpolator()
            setDuration(500)
            playTogether(scaleX,scaleY)
        }.start()

    }

    override fun animateContentOut(delay: Int, duration: Int) {
        TODO("Not yet implemented")
    }

}

Take note that there is a simple scale animation as the Snackbar appears. Now setting the clipToPadding to false is important to avoid the image from clipping because of OvershootInterpolator.

Extending BaseTransientBottomBar

We are now at the point to create an equivalent class for the Snackbar.

The custom Snackbar constructor accepts two params: one for the parent view and another for the custom view that supports the implementation of ContentViewCallback.

class CustomSnackbar(parent: ViewGroup, content: CustomSnackbarView) : BaseTransientBottomBar<CustomSnackbar>(parent, content, content) {

}

Now to implement the entry point method make(). As stated earlier in this post, there are three things to accomplish:

  • There is no reason to attempt and recreate the wheel so we will borrow the logic from the Snackbar’s source code
internal fun View?.findParent(): ViewGroup? {

    var view = this
    var fallback: ViewGroup? = null

    do {
        if (view is CoordinatorLayout) {
            //the Coordinator layout has been found
            return view
        } else if (view is FrameLayout) {
            if (view.id == android.R.id.content) {
                //coordinator layout not found so we need to use the appropriate hierarchy
                return view
            } else {
                //if no view assign the fallback
                fallback = view
            }
        }

        if (view != null) {
            //will continue to search for the view
            val parent = view.parent
            view = if (parent is View) parent else null
        }
    } while (view != null)

    return fallback
}
  • Inflate the custom view
    • inflating a custom view is best done by using the XML layout
<?xml version="1.0" encoding="utf-8"?>
<com.programmingninja.advancesnackbar.snackbar.CustomSnackbarView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="8dp" />
  • Build and correct errors
class CustomSnackbar(parent: ViewGroup, content: CustomSnackbarView) : BaseTransientBottomBar<CustomSnackbar>(parent, content, content) {

    companion object {
        fun make(view: View) : CustomSnackbar{

            //set parent for this view
            val parent = view.findParent() ?: throw IllegalArgumentException("No suitable parent found from the correct view. Please correct.")

            //custom view inflated
            val customView = LayoutInflater.from(view.context).inflate(R.layout.activity_snackbar, parent, false) as CustomSnackbarView

            //creation and return this new snackbar
            return CustomSnackbar(parent, customView)
        }

    }
}

If we attempt to run the code, you will notice that there is a gray background and padding. Why is this? This is because the BaseBottomTransientBar implementation is wrapped with the SnackbarBasrLayout. The workaround for this issue is simple enough by adding an init() block

init {
        getView().setBackgroundColor(ContextCompat.getColor(view.context, android.R.color.transparent))
        getView().setPadding(0,0,0,0)
}

Wrapping it altogether

Modify the MainActivity with the following

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<View>(R.id.btn_catch_em).setOnClickListener {
            CustomSnackbar.make(it).show()
        }
    }
}

Now we need to modify the main activity layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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.AppCompatButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btn_catch_em"
        android:layout_margin="8dp"
        android:text="Throw Poke Ball"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

androidandroid developmentandroidxkotlinMobile Development
Read more
  • Published in Android, Kotlin, Programming Languages, Tutorial
No Comments

Show/Hide On-Screen Keyboard

Friday, 11 December 2020 by Dauris

Android R is also known as Android 11 release brought a few new APIs to the table and one of them is the new WindowInset which expands the control that we as developers have over the window insets. This includes the navigation and status bar as well as an on-screen keyboard.

This new release provides a direct way to check these state changes that now toggle and listen for changes in the visibility of the window insets. These options now allow the developer to control and react to the animation when the visibility state changes (but this is not going to be covered within this article).

Getting Started

When writing this post, Android 11 been running on more than 1% of devices, but thanks to the magic of AndroidX the APIs are also usable on several other devices with earlier versions. This post focus on using AndroidX implementation but you will find the equivalent APIs to use in documentation.

implementation "androidx.core:core-ktx:1.5.0-alpha05

Now we are going to insert the following code into the build.gradle file, under all the dependencies. (Note: Any version of 1.5.0 or later will work and please check for the latest version. Apply accordingly)

Show/Hide Keyboard

To start we need to access the WindowInsetsController. When the view is passed it doesn’t have to be an EditText directly but can be any view in the same hierarchy as the focused editText.

//note: ci is my shorthand for controllerInsets
val ci = ViewCompat.getWindowInsetsController(view)

Now that we have initialized the view let show the keyboard on the screen:

ci?.show(WindowInsetsCompat.Type.ime())

Let’s hide the keyboard now:

ci?.hide(WindowInsetsCompat.Type.ime())

Keyboard Visibility

If you have ever tried to check the keyboard visibility in the past then you have probably messed with the global layout listeners because there was no other way. Well, hold on to your trousers because finally there is a proper way to do it.

//start by accessing the root window insets
val insets = ViewCompat.getRootWindowInsets(view)

//Now check the visibility of the IME window
insets?.isVisible(WindowInsetsCompat.Type.ime())

Catching Keyboard Changes

To catch the changes with the keyboard visibility, then we have to let the device know that the app is now responsible for the content view of the insets.

//add the following now
WindowCompat.setDecorFitsSystemWindows(window, false)

This will force the view to be drawn behind the on-screen keyboard as well as other system UI, however, now that we are listening for the keyboard changes we can move any other conflicting views accordingly.

Conclusion

Controlling the on-screen keyboard is common in Android development, so the APIs are long overdue. Understand that this now provides us (developers) a more reliable and efficient way to control any type of window insets going forward. Also, note that AndroidX allows us to use these APIs with older Android versions as well.

androidandroid developmentandroid keyboardandroidxjavakotlin
Read more
  • Published in Android, Java, Kotlin, Programming Languages
No Comments

Android, SQLite & Kotlin

Friday, 14 August 2020 by Dauris

The name of the database in Android is SQLite. SQLite is the name of the open-source sql database that stores the data in the text file in the device. Here, we will be review and explaining how to execute them with the Kotlin language. 

 

Before diving into the implementation we are going to review a little in details regarding the SQLite class. There are many methods available in the SQLiteDatabase class but the ones we will use are below

MethodDescription
execSQL(): UnitExecutes the SQL query, this is not to be mistaken for a select query
insert(): LongInsert a record into the database
update(): IntFires the update request on a select row
delete():
query(): CursorReturns a cursor over the resultset

HandlerDB

First we are going to create a class that extends to the SQLiteOpenHelper and override its onCreate(), onUpgrade() functions. 

  • CreatePerson – will insert the data by passing the ContentvValues to object to the insert() method
  • UpdatePerson – will update the record by passining the ContentValues to the update() method 
  • DeletePerson – will delete the record by passing the Content
  • ViewPerson – Will create a list adding the records to return to the view
package com.programmingninja.coeus.helper

import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteException
import android.database.sqlite.SQLiteOpenHelper
import com.programmingninja.coeus.model.PersonModel
import java.time.LocalDateTime

import kotlin.collections.ArrayList

class HandlerDB (context: Context): SQLiteOpenHelper(context, DATABASE_NAME,null,DATABASE_VERSION) {
    companion object {
        private val DATABASE_VERSION = 1
        private val DATABASE_NAME = "ProjectTitan"
        private val TABLE_NAME = "Person"
        private val KEY_ID = "userid"
        private val KEY_USERNAME = "username"
        private val KEY_FIRST_NAME = "firstname"
        private val KEY_LAST_NAME = "lastname"
    }

    override fun onCreate(db: SQLiteDatabase?) {
        //creating the table and columns
        val CREATE_PERSON_TABLE = ("CREATE TABLE $TABLE_NAME (" +
                "$KEY_ID TEXT PRIMARY KEY," +
                "$KEY_USERNAME TEXT," +
                "$KEY_FIRST_NAME TEXT," +
                "$KEY_LAST_NAME TEXT," +
                "timestamp DEFAULT CURRENT_TIMESTAMP)")
        db?.execSQL(CREATE_PERSON_TABLE)
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        db!!.execSQL("DROP TABLE IF EXISTS $TABLE_NAME")
    }

    //method to read data
    fun ViewPerson(): List&lt;PersonModel> {
        val personList:ArrayList&lt;PersonModel> = ArrayList()
        val personCandidates = "SELECT * FROM $TABLE_NAME"
        val db = this.readableDatabase

        val cursor: Cursor?
        try {
            cursor = db.rawQuery(personCandidates, null)
        } catch (e: SQLiteException) {
            db.execSQL(personCandidates)
            return ArrayList()
        }

        var userId: String
        var userName: String
        var fName: String
        var lName: String

        if (cursor.moveToFirst()) {
            do {
                userId = cursor.getString(cursor.getColumnIndex("userid"))
                userName = cursor.getString(cursor.getColumnIndex("username"))
                fName = cursor.getString(cursor.getColumnIndex("firstname"))
                lName = cursor.getString(cursor.getColumnIndex("lastname"))

                val person = PersonModel(userId = userId, userName = userName, fName = fName, lName = lName)
                personList.add(person)
            } while (cursor.moveToNext())
        }
        return personList
    }

    //method to create data
    fun CreatePerson(person: PersonModel): Long {
        val db = this.writableDatabase
        val cv = ContentValues()
        cv.put(KEY_ID, person.userId)
        cv.put(KEY_USERNAME, person.userName)
        cv.put(KEY_FIRST_NAME, person.fName)
        cv.put(KEY_LAST_NAME, person.lName)

        //now insert into the db
        val successfulInsert = db.insert(TABLE_NAME, null, cv)
        db.close()
        return successfulInsert
    }

    //method to update data

    fun UpdatePerson(person: PersonModel): Int {
        val db = this.writableDatabase
        val cv = ContentValues()

        cv.put(KEY_USERNAME, person.userName)
        cv.put(KEY_FIRST_NAME, person.fName)
        cv.put(KEY_LAST_NAME, person.lName)

        val whereClause = "${KEY_ID} = ?"
        val whereArgs = arrayOf(person.userId.toString())

        //attempt to update the record
        val successfulUpdate = db.update(TABLE_NAME, cv, whereClause, whereArgs)
        db.close()
        return successfulUpdate
    }

    //method to delete data
    fun DeletePerson(person: PersonModel): Int {
        val db = this.writableDatabase
        val cv = ContentValues()
        cv.put(KEY_ID, person.userId)

        val whereClause = "${KEY_ID} = ?"
        val whereArg = arrayOf(person.userId.toString())
        //delete candidate
        val successfulDelete = db.delete(TABLE_NAME, whereClause, whereArg)
        db.close()
        return successfulDelete
    }
}

activity_main.xml

Now we are going to work on the main xml layout. This is going to be the main display the user interacts with 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    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.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:orientation="vertical">

        <TableLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TableRow>
                <androidx.appcompat.widget.AppCompatTextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:hint="User ID"
                    android:layout_column="1"/>
                <androidx.appcompat.widget.AppCompatTextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/tv_userId"
                    android:layout_marginLeft="20dp"
                    android:layout_marginStart="20dp"
                    android:width="150dp"/>
            </TableRow>
            <TableRow>
                <androidx.appcompat.widget.AppCompatTextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:hint="Username"
                    android:layout_column="1"/>
                <androidx.appcompat.widget.AppCompatEditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/et_userName"
                    android:layout_marginLeft="20dp"
                    android:layout_marginStart="20dp"
                    android:width="150dp"/>
            </TableRow>
            <TableRow>
                <androidx.appcompat.widget.AppCompatTextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:hint="First Name"
                    android:layout_column="1"/>
                <androidx.appcompat.widget.AppCompatEditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/et_fName"
                    android:layout_marginLeft="20dp"
                    android:layout_marginStart="20dp"
                    android:width="150dp"/>
            </TableRow>
            <TableRow>
                <androidx.appcompat.widget.AppCompatTextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:hint="Last Name"
                    android:layout_column="1"/>
                <androidx.appcompat.widget.AppCompatEditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/et_lName"
                    android:layout_marginLeft="20dp"
                    android:layout_marginStart="20dp"
                    android:width="150dp"/>
            </TableRow>

        </TableLayout>
        <androidx.appcompat.widget.LinearLayoutCompat
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp">

            <ListView
                android:id="@+id/listView"
                android:layout_width="wrap_content"
                android:layout_height="350sp"
                android:longClickable="false" />
        </androidx.appcompat.widget.LinearLayoutCompat>

        <androidx.appcompat.widget.LinearLayoutCompat
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="40dp"
            android:orientation="horizontal"
            android:layout_gravity="center">
            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="View"
                android:id="@+id/pressMe"
                android:onClick="ViewRecord" />
            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Save"
                android:onClick="SaveRecord" />
            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Update"
                android:onClick="UpdateRecord" />
            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Delete"
                android:onClick="DeleteRecord" />
        </androidx.appcompat.widget.LinearLayoutCompat>
    </androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>

Update Person Alert

//creat the layout to display an alertdialog to update request item
<?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:padding="10dp"
    android:orientation="vertical">

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tv_userId_update"
        android:ems="10"
        android:text="User Id"/>

    <androidx.appcompat.widget.AppCompatEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_nameUser_update"
        android:ems="10"
        android:hint="username"/>

    <androidx.appcompat.widget.AppCompatEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_firstname_update"
        android:ems="10"
        android:hint="first name"/>

    <androidx.appcompat.widget.AppCompatEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_lastname_update"
        android:ems="10"
        android:hint="Last Name"/>
</LinearLayout>

Delete Person Alert

<?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:padding="10dp">

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tv_userId_delete"
        android:textSize="20dp"
        android:text="userid" />

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tv_Name_delete"
        android:textSize="20dp"
        android:text="Name"/>

</LinearLayout>

MainActivity.kt

Now we are focusing on the MainActivity.kt class and we are going to add the following code. In this class, the following functions are going to be added:

  • saveRecord() function which creates the records.
  • viewRecord() function will read all the records and displays them into ListView,
  • updateRecord() function updates the record on the basis on id, and
  • deleteRecord() function deletes the record.

The val db = DatabaseHandler(this) creates the instance of HandlerDB class calls the SQLite database logic.

package com.programmingninja.coeus

import android.content.DialogInterface
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.AppCompatButton
import androidx.appcompat.widget.AppCompatEditText
import androidx.appcompat.widget.AppCompatTextView
import com.programmingninja.coeus.helper.HandlerDB
import com.programmingninja.coeus.helper.MyListadapter
import com.programmingninja.coeus.model.PersonModel
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main.view.*
import kotlinx.android.synthetic.main.update_person.*
import java.util.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    //method for reviewing records
    fun ViewRecord (view:View) {
        //creating the instance of the db handler
        val dbHandler = HandlerDB(this)
        //calling the person view
        val person: List<PersonModel> = dbHandler.ViewPerson()
        val personArrayId = Array<String>(person.size){"0"}
        val personArrayUsername = Array<String>(person.size){""}
        val personArrayFirst = Array<String>(person.size){""}
        val personArrayLast = Array<String>(person.size){""}

        for ((index, p) in person.withIndex()) {
            personArrayId[index] = p.userId
            personArrayUsername[index] = p.userName
            personArrayFirst[index] = p.fName
            personArrayLast[index] = p.lName
        }
        //creating custom adapter
        val listAdapter = MyListadapter(this, personArrayId, personArrayUsername, personArrayFirst, personArrayLast)
        listView.adapter = listAdapter
        listView.onItemClickListener = AdapterView.OnItemClickListener {
                adapterView, view, position, id -> 
            //Toast.makeText(applicationContext, "${person[position].userId}",Toast.LENGTH_LONG).show()
            UpdateRecord(person[position].userId)
        }
        listView.onItemLongClickListener = AdapterView.OnItemLongClickListener {
            adapterView, view, position, l ->
            DeleteRecord(person[position].userId, person[position].fName + " " +  person[position].lName)
        }
    }
    //method for deleting a record
     fun DeleteRecord(deleteUserId: String, deleteUserName: String): Boolean {
        //create AlertDisplay
        val alertDialog = AlertDialog.Builder(this)
        val inflater = this.layoutInflater
        val dv = inflater.inflate(R.layout.delete_person, null)

        alertDialog.setView(dv)

        val delete_id = dv.findViewById<AppCompatTextView>(R.id.tv_userId_delete)
        val delete_name = dv.findViewById<AppCompatTextView>(R.id.tv_Name_delete)
        delete_id.text = deleteUserId
        delete_name.text = deleteUserName
        val deletePersonId = delete_id.text

        alertDialog.setTitle("Delete User")
        alertDialog.setMessage("Are you sure you want to delete the user")
        alertDialog.setPositiveButton("Yes, Delete", DialogInterface.OnClickListener { _,_->
            //creating the instance of the handler
            val db = HandlerDB(this)

            //calling the delete method within the handler
            val status = db.DeletePerson(PersonModel(deletePersonId.toString(),"","",""))
            if (status > -1) {
                Toast.makeText(applicationContext, "User has been deleted", Toast.LENGTH_LONG).show()
                val buttonPress = findViewById<AppCompatButton>(R.id.pressMe)
                buttonPress.performClick()
            }
        })

        alertDialog.setNegativeButton("Cancel", DialogInterface.OnClickListener { _, _->

        })
        val b = alertDialog.create()
        b.show()
        return false
    }

    //method for updating a record
     fun UpdateRecord(updatingUser: String) {
        val alertBuilder = AlertDialog.Builder(this)
        val inflater = this.layoutInflater
        val dv = inflater.inflate(R.layout.update_person, null)
        val uPersonUserId = dv.findViewById(R.id.tv_userId_update) as AppCompatTextView
        val uPersonUsername = dv.findViewById(R.id.et_nameUser_update) as AppCompatEditText
        val uPersonFirstName = dv.findViewById<AppCompatEditText>(R.id.et_firstname_update)
        val uPersonLastName = dv.findViewById(R.id.et_lastname_update) as AppCompatEditText
        uPersonUserId.text = updatingUser
        val updatePersonId = uPersonUserId.text
        val updatePersonUsername = uPersonUsername.text
        val updatePersonFirst = uPersonFirstName.text
        val updatePersonLast = uPersonLastName.text

        alertBuilder.setTitle("Update Person")
        alertBuilder.setMessage("Update person data")
        alertBuilder.setPositiveButton("Update", DialogInterface.OnClickListener { _, _->
            //creating an instance of the handler class
            val db = HandlerDB(this)
            if (!updatePersonUsername.isNullOrEmpty() && !updatePersonFirst.isNullOrEmpty() && !updatePersonLast.isNullOrEmpty()) {
                val status = db.UpdatePerson(PersonModel(updatePersonId.toString(), updatePersonUsername.toString(), updatePersonFirst.toString(), updatePersonLast.toString()))

                if (status>-1) {
                    Toast.makeText(applicationContext,"Record Update", Toast.LENGTH_LONG).show()
                    val buttonPress = findViewById<AppCompatButton>(R.id.pressMe)
                    buttonPress.performClick()
                }
            } else {
                Toast.makeText(applicationContext, "username, first and last name required", Toast.LENGTH_LONG).show()
            }
        })

        alertBuilder.setNegativeButton("Cancel", DialogInterface.OnClickListener { di, which ->  })
        alertBuilder.setView(dv)
        val b = alertBuilder.create()
        b.show()
    }

    //method for saving the records
    fun SaveRecord (view: View) {
        val id = UUID.randomUUID()
        val uName = et_userName.text.toString()
        val fName = et_fName.text.toString()
        val lName = et_lName.text.toString()
        val db_handler: HandlerDB = HandlerDB(this)

        if (uName.trim().isNotEmpty() || fName.trim().isNotEmpty() || lName.trim().isNotEmpty()) {
            val status = db_handler.CreatePerson(PersonModel(id.toString(), uName, fName, lName))
            if (status > -1) {
                Toast.makeText(applicationContext, "Person saved", Toast.LENGTH_LONG).show()
                et_userName.setText("")
                et_fName.setText("")
                et_lName.setText("")
            }
        } else {
            Toast.makeText(applicationContext, "Username, First Name and Last Name is required", Toast.LENGTH_LONG).show()
        }
    }
}

PersonModel.kt

package com.programmingninja.coeus.model

class PersonModel (var userId: String, val userName: String, val fName: String, val lName: String) {
}

custom_list.xml

//create a custom row layout for displauong the list items in the ListView
<?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:id="@+id/lLayout">
    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tv_userId"
        android:text="User Id"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tv_nameU"
        android:text="Username"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tv_nameF"
        android:text="First Name"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

    <androidx.appcompat.widget.AppCompatTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tv_nameL"
        android:text="Last Name"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

</LinearLayout>

MyListadapter

//Now, we create the adapter that will populate the data model within the listview
package com.programmingninja.coeus.helper

import android.app.Activity
import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import androidx.appcompat.widget.AppCompatTextView
import com.programmingninja.coeus.R

class MyListadapter (private val context: Activity, private val idUser: Array&lt;String>, private val nameUser: Array&lt;String>, private val userFirst: Array&lt;String>, private val userLast: Array&lt;String>)
    : ArrayAdapter&lt;String>(context, R.layout.custom_list, nameUser)
{
    override fun getView(position: Int, view: View?, parent: ViewGroup): View {
        val inflater = context.layoutInflater
        val rowView = inflater.inflate(R.layout.custom_list, null, true)

        val idUserTxt =  rowView.findViewById(R.id.tv_userId) as AppCompatTextView
        val nameUserTxt =  rowView.findViewById(R.id.tv_nameU) as AppCompatTextView
        val nameFTxt =  rowView.findViewById(R.id.tv_nameF) as AppCompatTextView
        val nameLTxt =  rowView.findViewById(R.id.tv_nameL) as AppCompatTextView

        idUserTxt.text = "User Id: ${idUser[position]}"
        nameUserTxt.text = "Username: ${nameUser[position]}"
        nameFTxt.text = "First Name: ${userFirst[position]}"
        nameLTxt.text = "Last Name: ${userLast[position]}"
        return rowView
    }
}
androidkotlinsqlite
Read more
  • Published in Android, Kotlin, Programming Languages
No Comments

When over Switch in Kotlin

Thursday, 13 August 2020 by Dauris

Good afternoon Programming Community, I am glad to welcome you to another Kotlin edition. we will look upon the replacement of switch with the when keyword. Firstly, we will look on to some examples of switch and after that, we will look at how the when keyword makes our task or code easier and more understandable. So, let’s get started.

Standard Conditional

if (number == 1) { 
   println("value: 1") 
} else if (nummber == 2) { 
   println("value: 2") 
} else if (number == 3) { 
   println("value: 3") 
} else if (number == 4) { 
   println("value 4") 
} else { 
   println("value greater 5") 
}

A traditional switch is basically just a statement that can substitute a series of simple if/else that make basic checks as displayed above. However it cannot replace all sort of if/else sequences but just those which compare a value with some constant. So, you can only use a switch to perform an action when one specific variable has a certain precise value.

To remove this difficulty, switch-case was introduced, where we pass the variable to be compared with-in the switch statement (in our example, that variable is number) and compare it with various case statements present corresponding to it and do the operation. 

‘switch’

switch (number) {
   case 1:
      println("value: 1")
      break;
   case 2:
      println("value: 2")
      break;
   case 3:
      println("value: 3")
      break;
   case 4:
      println("value: 4")
      break;
   default:
      println("value greater 5")
      break;
}

So, in the above code in order to print the numbers in word, you have to use various conditional statements and this results in a large number of lines of code. Think of a situation when you have to print the words representation of numbers up to 100 or 1000. If you are using conditional statements then you have to use 1000 conditional statements.

In the above code, number is passed in switch statement and cases are used to compare that number. For example, if the number is 1 then case 1 will be executed, if number is 2 then case 2 will be executed and so on. But if the number is not equal to any of the case present then the default block will be executed.

‘when’

when {
   number == 1 -> {
       println("value: 1")
   }
   nummber == 2 -> {
       println("value: 2")
   }
   number == 3 -> {
       println("value: 3")
   }
   number == 4 -> {
       println("value 4")
   }
   else -> {
       println("value greater 5")
   }
}

So, if you are moving from Java to Kotlin, then you will find some changes in the syntax part also. In Java we use switch but in Kotlin, that switch gets converted to when. when is also used for conditional representation but it does the things in a very smarter and easier way. Whenever you are having a number of possibilities then you can use when in your code.

In the above code, like in switch, the number is passed in when and then we compare that number with various options available. In our case, if the number == 1, then “one” will be printed and so on. If more than one match is found then the match that occurs first will be considered only. If no match to the number is found then the else part will be executed.

When in doubt use ‘when’

  • no complex case/break groups, only the condition followed by ->
  • it can group two or more equivalent choices, separating them with a comma

Wrapping Things Up

we learned how to use when in place of switch in Kotlin. We saw that, if we are having a number of possibilities for a particular variable then we can make use of when to handle all the possibilities. Also, we can use when for multiple or more than one choices.

androidandroid developmentkotlinreplace switch with whenswitchswitch vs when
Read more
  • Published in Android, Kotlin, Programming Languages
No Comments

Val vs Var

Saturday, 09 May 2020 by Dauris
val vs var

Any programming language a variable is referred to a location in memory(storage area) to stored data. The type of variable defines the range of value that the variable can hold. So indicate a storage space, each variable should be given a unique identifier.

Basically, val and var both are used to declare a variable. var is like a general variable and can be assigned multiple times and is known as the mutable variable in Kotlin. Whereas val is a constant variable and can not be assigned multiple times and can be Initialized only single time and is known as the immutable variable in Kotlin.

Declaring a variable in Kotlin

Var

is short for variable – The object stored in the variable could change (vary) in time.

private val adapter: HomeAdapter? = null

After the Initialized It will not throw me an error because var is a mutable and it can be assigned multiple times.

Val

is short for value – The object stored in val, could not vary in time. Once assigned the val becomes read only, like a constant in Java Programming language.

private var adapter: HomeAdapter? = null

After the Initialized It will throw me an error like “Val can not be reassigned”

So to conclude we have learnt about Val vs Var in Kotlin that var could be changed at any level. Whereas val once assigned, could not be changed, but its properties could be changed.

androidandroid developmentdeclaring variableskotlinvalvarvariables
Read more
  • Published in Android, Kotlin, Programming Languages, Uncategorized
No Comments

Android w/ Fragments

Sunday, 03 May 2020 by Dauris

A fragment is an Android component that holds part of the behavior and/or UI of an activity. As the name would suggest, fragments are not independent entities, but are tied to a single activity. In many ways, they have functionality similar to activities.

In the same way that you don’t actually need an army of little helpers to do your bidding, you don’t have to use fragments. However, if you use them well, they can provide:

  • Modularity – Diving complex activity code across fragments for better maintenance
  • Adaptability – representing sections of a UI within the different fragments while utilizing different layouts that relys on the screen orientation and size
  • Reusability – placing behavior or UI parts within the fragments that multiple activities can share

Fragment Lifecycle of Android

As you already know like activity, a fragment has a lifecycle with events that occur when the status changes within the framents. For example, when an event fires becasue a fragment becomes visible and active, or is not used or removed. Just as in a regular activity you are able to add code and behavior to the callbacks for the events.

Below you will see the fragment lifescycle diagram:

Diagram designed by Android Developer documentation

Understanding the lifecycle

  • onAttach : the fragment attaches to its host activity
  • onCreate : When a new fragment initializes, which always happens after it attaches to the hosts.
  • onCreateView : creates its portion of the view hierarchy, which then added to the activity’s hierarchy of view
  • onActivityCreated : fragment’s activity has finished on its own onCreate
  • onStart : fragment becomes visible and starts after its activity starts 
  • onResume : fragment is visible and interactable that resumes only after its activity resumes and often resumes immediately after the activity does.
  • onPause : user may not interact
  • onStop : this is fired when the fragment is no longer visible; the fragment will get change with another fragment or it gets removed from actvity or fragment’s is stopped
  • onDestroyView : this is fired when the view and other resources created within the onCreateView() are removed from the activity’s view hierarchy and destroyed.
  • onDestroy : fired when the fragment does the final clean up.
  • onDetach : fires when the fragment is detached from the activity host

If you want to learn more details regarding please read “Droid Fragments Life”.This is all about how the fragment come up within the activity and goes out. Cool!!  

androidandroid developmentfragmentfragmentsjavakotlin
Read more
  • Published in Android, Java, Kotlin, Programming Languages
No Comments

Java Or Kotlin Language: Deciding Which Option to Use for Android Development

Friday, 13 March 2020 by Dauris
Java vs Kotlin

If my math is not wrong Java has been around for over 20+ years now and has no intention of going away. It holds a supreme position in the list of most popular programming languages following the C and C++ =, setting the highest usability record with millions of developers and systems.

Random Fact:

James Gosling, Mike Sheridan, and Patrick Naughton initiated the Java language back in 1991. Java has been the primary language for Android app development along with a few of its companions: Scala, Groovy and stepping up is Kotlin.

Kotlin Background

Let first you will need to understand what exactly is Kotlin so it is considered as statically typed programming language that runs on JVM(Java Virtual Machine) and JavaScript. It is developed by JetBrains and open-source community. The ‘Kotlin’ name came from Kotlin Island located near Saint Petersburg. It is supported by leading IDEs and compatible with Java 6 or Java 8. Kotlin is described as a general-purpose language and introduces functional features to support Java interoperability. The Kotlin project was born out of the aspiration for heightened productivity. The goal was to improve the coding experience in a way that was both practical and effective.

A central focus of Kotlin is to enable mixed-language projects. Kotlin also introduces improved syntax, as well as concise expressions and abstractions. Using Kotlin with Java reduces excessive boilerplate code, which is a huge win for Android developers. Kotlin came when Android development needed a more modern language to add to the qualities of java and aid in mobile development. This allows developers to not only easily update old Java apps to Kotlin, but also carry on their old work in Java to Kotlin.

Here’s a brief example Kotlin language

package hello
fun main() {
  println("Hello World")
}

It’s that simple! Kotlin uses developer-friendly coding structures and norms that are easy-to-understand and use. When considering this example from the develops’ perspective, you will be able to understand why Kotlin is loved by developers around the world. It is concise, effective, and faster compared to Java.

Is Java Dead?

Based on the group that I program with it appears that Java is currently in the area with us developers. Java is a reputable programming language with vast open-source tools and libraries to help developers. With that said, no language is without fault and even Java is subject to complications that can make a developer’s job tedious. If anything the objective for Kotlin is to supposedly introduce solutions to the common programming headaches and improve the Java ecosystem as a whole.

Strict Trial And Error

Kotlin has some milage under itself and has become a more stable and congruous development option especially within the Android Studio IDE. Some developers seem to believe that Kotlin will oust Java for Android development in future years. Other reviewers seem to believe Kotlin and Java should be coexisting without one outweighing the other.

This is a quality Java is not known for; however, readability should always take priority over concision. Yes, the succinct nature of Kotlin simplifies a developer’s job and mitigates the risk for error, but Kotlin doesn’t practice concision for concision’s sake. So let’s take the example below and compare the difference in the languages presents.

public class MathLife {
   public static double calculate () throws Exception {
      switch(op) {
         case "add":
            return a + b;
         case "subtract":
            return a - b;
         case "multiply":
            return a * b;
         case "divide":
            return a / b;
         default:
            throw new Exception();
      }
   }
}

Above is a simple calculator function written in Java. For comparison, here is the same calculator in Kotlin:

fun calculate(a: Double, op: String, b: Double): Double {
   when (op) {
      "add" -> return a + b
      "subtract" -> return a - b
      "multiply" -> return a * b
      "divide" -> return a / b
      else -> throw Exception()
   }
}

It may not seem like much, but the Kotlin version of this calculator is written in half the lines of code it took to program the function in Java. Brevity is a crucial factor in productivity. Writing large projects becomes easier when a developer is given more power for every line of code. A key observation here is Kotlin does not overlook comprehension for the sake of brevity. The syntax is concise, readable and still substantial.

The Winner: Java or Kotlin

In all fairness, chances are that you have been taught, learn and embraced Java. Switching to Kotlin at a time can be a bit of shock, so it is important to do this transition slowly to make sure you understand. having said that, Kotlin is the new official language and owing to its modern nature, it will become widely adopted in the future, so learning it and starting development with it right now would be a good idea. Understand java will continue to be a popular language for several years to come and isn’t likely to be entirely replaced. So take your time and make the switch gently.

At the end of the day, it’s all about what you feel comfortable with. As stated previously to be a true blood Androidian, you will need to have a working knowledge of the language Java. But if you already do have that then the Kotlin language of the future, so you might as well spend some time getting accustomed to it.

androidandroid developmentdevelopmentjavakotlinnew vs oldprogrammingprogramming language
Read more
  • Published in Android, Java, Kotlin, Language, Programming Languages
3 Comments

All rights reserved. 

TOP
This site uses tracking cookies to personalize content and ads. AcceptLearn More