Showing posts with label Kotlin. Show all posts
Showing posts with label Kotlin. Show all posts

Thursday, 6 July 2023

Gradle and Maven: Powerful Library Platforms for Building Java Projects.

 In the world of Java development, the choice of a build tool is crucial for efficient project management. Two of the most popular build tools in the Java ecosystem are Gradle and Maven. These tools serve as powerful library platforms that automate the build process, manage dependencies, and provide a structured project organization. In this blog post, we will explore the key features and advantages of Gradle and Maven, highlighting their similarities and differences.

Gradle: A Modern and Flexible Build Tool

Gradle is a build automation tool that focuses on flexibility and extensibility. It employs a Groovy-based domain-specific language (DSL) or Kotlin to define build scripts, allowing developers to express complex build logic in a concise and readable manner. Gradle utilizes a declarative syntax that describes the desired state of the build, making it easy to understand and maintain.

One of the main advantages of Gradle is its support for incremental builds. By tracking the dependencies between tasks, Gradle can intelligently determine which parts of the project need to be rebuilt, resulting in faster build times. Additionally, Gradle provides a rich plugin ecosystem, allowing developers to extend its functionality and integrate with various tools and frameworks effortlessly.

Maven: Dependency Management and Convention over Configuration

Maven is a popular build tool and dependency management system that emphasizes convention over configuration. It uses XML-based configuration files, known as Project Object Models (POMs), to define project structure, dependencies, and build settings. Maven follows a standardized directory structure, making it easier for developers to navigate and understand projects built with Maven.

One of the key strengths of Maven is its comprehensive dependency management. Maven uses a centralized repository called Maven Central, which hosts a vast collection of pre-built libraries and dependencies. With Maven, you can easily declare and manage dependencies, and Maven takes care of downloading the required libraries automatically. This ensures that your project is always built with the correct versions of dependencies, simplifying the development process and avoiding version conflicts.

Gradle vs. Maven: Similarities and Differences

While both Gradle and Maven serve as powerful build tools, there are some notable differences between them. Here's a comparison of their key features:

  • Build Scripting: Gradle uses a Groovy or Kotlin-based DSL, offering a flexible and expressive way to define build scripts. Maven uses XML-based POM files, which provide a more standardized and convention-based approach.
  • Dependency Management: Both Gradle and Maven offer excellent dependency management capabilities. Maven relies on a centralized repository, while Gradle supports multiple repositories and even allows you to define custom repositories.
  • Plugin Ecosystem: Gradle has a vibrant and extensible plugin ecosystem, making it easy to integrate with various tools and frameworks. Maven also provides a wide range of plugins, although it may have fewer options compared to Gradle.
  • Performance: Gradle's incremental build feature often leads to faster build times, especially for large projects. Maven, on the other hand, may require a full build when there are changes to any part of the project.

Conclusion:

Choosing between Gradle and Maven ultimately depends on your project requirements, team preferences, and the complexity of your build process. Both Gradle and Maven are robust build tools that offer powerful dependency management, project organization, and automation features. Gradle excels in flexibility and extensibility, while Maven focuses on convention and simplicity. Whichever tool you choose, embracing either Gradle or Maven will undoubtedly enhance your Java project's productivity and maintainability.

Monday, 14 October 2019

Using Google Maps SDK For Android Using Kotlin.

We know that with the Maps SDK for Android, you can add maps based on Google Maps data to your application. The API automatically handles access to Google Maps servers, data downloading, map display, and response to map gestures. You can also use API calls to add markers, polygons, and overlays to a basic map, and to change the user's view of a particular map area. These objects provide additional information for map locations, and allow user interaction with the map.

Now, lets try the same with Kotlin,

Refer the below link for complete sample code:-

Download Sample Code

Have a look on few code snippets,

//MapsActivity.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package com.elitetechnologies.googlemapkotlin

import android.content.pm.PackageManager
import android.graphics.Color
import android.location.Location
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v7.app.AppCompatActivity
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.Marker
import com.google.android.gms.maps.model.MarkerOptions
import com.google.android.gms.maps.model.PolylineOptions



class MapsActivity : AppCompatActivity(), OnMapReadyCallback, GoogleMap.OnMarkerClickListener {
    companion object {
        private const val LOCATION_PERMISSION_REQUEST_CODE = 1
    }

    private lateinit var mMap: GoogleMap
    private lateinit var fusedLocationClient: FusedLocationProviderClient
    private lateinit var lastLocation: Location

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_maps)
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    }

    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap
        mMap.uiSettings.isZoomControlsEnabled = true
        mMap.setOnMarkerClickListener(this)
        setUpMap()
    }

    override fun onMarkerClick(p0: Marker?): Boolean {
        // Add a marker in Sydney and move the camera
        val sydney = LatLng(-34.0, 151.0)
        var marker = mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
        marker.showInfoWindow()
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
        return true
    }

    private fun setUpMap() {
        if (ActivityCompat.checkSelfPermission( this,android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), LOCATION_PERMISSION_REQUEST_CODE
            )
        }

        mMap.isMyLocationEnabled = true
        fusedLocationClient.lastLocation.addOnSuccessListener(this) { location ->
            // Got last known location. In some rare situations this can be null.
            // 3
                lastLocation = location
                val currentLatLng = LatLng(location.latitude, location.longitude)
                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 12f))

                val markerLocation = LatLng(location.latitude + 2, location.longitude)
                var marker = mMap.addMarker(MarkerOptions().position(markerLocation).title("marker postion"))
                marker.showInfoWindow()

                val polylineOptions = PolylineOptions()
                polylineOptions.add(currentLatLng)
                    .add(LatLng(location.latitude + 2, location.longitude))
                    .add(LatLng(-34.0, 151.0))
                    .width(5f)
                    .color(Color.RED)
                mMap.addPolyline(polylineOptions)
        }
    }
}

Friday, 14 December 2018

HB Blog 162: View-pager In Android Using Kotlin.

Hey friends, we have seen listview using Kotlin as well as combination of Jetpack Architecture with Kotlin language.

Kotlin Listview Tutorial : - HB Blog 157: Listview In Android Using Kotlin.

Jetpack Architecture : - HB Blog 161: Jetpack Architecture: - Room And Live Data In Kotlin.

In this tutorial, I will show how to create a viewpager with custom adapter in Kotlin Android Application,
Refer the below link for complete sample code:-

Download Sample Code

Have a look on few code snippets,

//activity_main.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">

    <android.support.design.widget.TabLayout
        android:id="@+id/tablayout_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed" />


    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

//CustomPagerAdapter.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.harshalbenake.kotlinviewpager.adapter

import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentPagerAdapter
import com.caressa.libs.leaderboard.ui.fragments.FirstFragment
import com.caressa.libs.leaderboard.ui.fragments.SecondFragment

class CustomPagerAdapter(fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager) {

    override fun getItem(position: Int): Fragment {
        return when (position) {
            0 ->FirstFragment()
            else -> {
                return SecondFragment()
            }
        }
    }

    override fun getCount(): Int {
        return 2
    }

    override fun getPageTitle(position: Int): CharSequence {
        return when (position) {
            0 -> "First"
            else -> {
                return "Second"
            }
        }
    }
}

//MainActivity.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.harshalbenake.kotlinviewpager

import android.os.Bundle
import android.support.v4.app.FragmentActivity
import android.view.MenuItem
import com.harshalbenake.kotlinviewpager.adapter.CustomPagerAdapter
import kotlinx.android.synthetic.main.activity_main.*

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

    override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
        android.R.id.home -> {
            onBackPressed()
            true
        }
        else -> false
    }
    /**
     * init Layout
     */
    private fun initLayout() {
        val fragmentAdapter = CustomPagerAdapter(supportFragmentManager)
        viewpager_main.adapter = fragmentAdapter
        tablayout_main.setupWithViewPager(viewpager_main)
    }
}

Wednesday, 14 November 2018

HB Blog 161: Jetpack Architecture: - Room And Live Data In Kotlin Language.

In my previous, post we saw Listview Using DataBinding In Kotlin Language,

In this post, lets store data using Room And Live data,

Room is an a SQLite object mapping library. Use it to Avoid boilerplate code and easily convert SQLite table data to Java objects. Room provides compile time checks of SQLite statements and can return RxJava, Flowable and LiveData observables.

Manage your app's lifecycle with ease. New lifecycle-aware components help you manage your activity and fragment lifecycles. Survive configuration changes, avoid memory leaks and easily load data into your UI.

Use LiveData to build data objects that notify views when the underlying database changes.

ViewModel Stores UI-related data that isn't destroyed on app rotations.
Refer the below link for complete sample code:-

Download Sample Code

Have a look on few code snippets,
//build.gradle
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:27.0.2'
    implementation 'com.android.support:design:27.0.2'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:+"
    //room
    implementation 'android.arch.persistence.room:runtime:1.0.0'
    kapt"android.arch.persistence.room:compiler:1.0.0"
    //Lifecycle
    implementation 'android.arch.lifecycle:extensions:1.0.0'
    annotationProcessor "android.arch.lifecycle:compiler:1.0.0"
}

//activity_addperson.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="16dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tv_name"
                android:layout_width="150dp"
                android:layout_height="wrap_content"
                android:gravity=""
                android:text="name :"
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption" />

            <EditText
                android:id="@+id/et_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="enter name"
                android:inputType="text"
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tv_age"
                android:layout_width="150dp"
                android:layout_height="wrap_content"
                android:text="Age :"
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption" />

            <EditText
                android:id="@+id/et_age"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="enter age"
                android:inputType="number"
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

//PersonProfile.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package com.harshalbenake.kotlinroomlivedata.data.model

import android.arch.persistence.room.ColumnInfo
import android.arch.persistence.room.Entity
import android.arch.persistence.room.PrimaryKey

@Entity(tableName = "personprofile")
data class PersonProfile(
        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(name = "idPerson")
        var idPerson: Int = 0,

        @ColumnInfo(name = "name")
        var name: String = "",

        @ColumnInfo(name = "age")
        var age: String = ""

)

//PersonProfileDAO.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.harshalbenake.kotlinroomlivedata.data

import android.arch.lifecycle.LiveData
import android.arch.persistence.room.*
import com.harshalbenake.kotlinroomlivedata.data.model.PersonProfile

@Dao
interface PersonProfileDAO {
    @Query("select * from personprofile")
    fun getAllPersonProfiles(): LiveData<List<PersonProfile>>

    @Query("select * from personprofile where age>18")
    fun getAllPersonProfilesAbove18(): PersonProfile

    @Query("select * from personprofile where idPerson in (:id)")
    fun getPersonById(id: Int): PersonProfile

    @Query("delete from personprofile")
    fun deleteAllPersonProfiles()

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertPersonProfiles(personProfile: PersonProfile)

    @Update
    fun updatePersonProfiles(personProfile: PersonProfile)

    @Delete
    fun deletePersonProfiles(personProfile: PersonProfile)
}

//PersonProfileDb.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.harshalbenake.kotlinroomlivedata.data

import android.arch.persistence.room.Database
import android.arch.persistence.room.Room
import android.arch.persistence.room.RoomDatabase
import android.content.Context
import com.harshalbenake.kotlinroomlivedata.data.model.PersonProfile

@Database(entities = [(PersonProfile::class)], version = 1, exportSchema = false)
abstract class PersonProfileDb : RoomDatabase() {
    companion object {
        private var INSTANCE: PersonProfileDb? = null
        fun getDataBase(context: Context): PersonProfileDb {
            if (INSTANCE == null) {
                INSTANCE = Room.databaseBuilder(context.applicationContext, PersonProfileDb::class.java, "personprofile-db")
                        .allowMainThreadQueries().build()
            }
            return INSTANCE as PersonProfileDb
        }
    }

    abstract fun personProfileDAO(): PersonProfileDAO
}

//PersonProfileViewModel.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.harshalbenake.kotlinroomlivedata.viewmodel

import android.app.Application
import android.arch.lifecycle.AndroidViewModel
import android.arch.lifecycle.LiveData
import android.os.AsyncTask
import com.harshalbenake.kotlinroomlivedata.data.model.PersonProfile
import com.harshalbenake.kotlinroomlivedata.data.PersonProfileDb

class PersonProfileViewModel(application: Application) : AndroidViewModel(application) {

    var listPersonProfile: LiveData<List<PersonProfile>>
    private val appDb: PersonProfileDb

    init {
        appDb = PersonProfileDb.getDataBase(this.getApplication())
        listPersonProfile = appDb.personProfileDAO().getAllPersonProfiles()
    }

    fun getListPersonProfiles(): LiveData<List<PersonProfile>> {
        return listPersonProfile
    }

    fun addersonProfile(personProfile: PersonProfile) {
        addAsynTask(appDb).execute(personProfile)
    }


    class addAsynTask(db: PersonProfileDb) : AsyncTask<PersonProfile, Void, Void>() {
        private var personProfileDb = db
        override fun doInBackground(vararg params: PersonProfile): Void? {
            personProfileDb.personProfileDAO().insertPersonProfiles(params[0])
            return null
        }

    }

}

//AddPersonActivity.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package com.harshalbenake.kotlinroomlivedata.ui

import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.widget.Toast
import com.harshalbenake.kotlinroomlivedata.R
import com.harshalbenake.kotlinroomlivedata.data.model.PersonProfile
import com.harshalbenake.kotlinroomlivedata.data.PersonProfileDAO
import com.harshalbenake.kotlinroomlivedata.data.PersonProfileDb
import com.harshalbenake.kotlinroomlivedata.viewmodel.PersonProfileViewModel
import kotlinx.android.synthetic.main.activity_addperson.*

//import kotlinx.android.synthetic.main.activity_contact_details.*

class AddPersonActivity : AppCompatActivity() {

    private var personProfileDAO: PersonProfileDAO? = null
    private var personProfileViewModel: PersonProfileViewModel? = null
    private var currentPersonProfile: Int? = null
    private var personProfile: PersonProfile? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_addperson)
        var personProfileDB: PersonProfileDb = PersonProfileDb.getDataBase(this)
        personProfileDAO = personProfileDB.personProfileDAO()
        personProfileViewModel = ViewModelProviders.of(this).get(PersonProfileViewModel::class.java)
        currentPersonProfile = intent.getIntExtra("idPerson", -1)
        if (currentPersonProfile != -1) {
            setTitle("Edit")
            personProfile = personProfileDAO!!.getPersonById(currentPersonProfile!!)
            et_name.setText(personProfile!!.name)
            et_age.setText(personProfile!!.age)
        } else {
            setTitle("Add")
            invalidateOptionsMenu()
        }
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        var inflater: MenuInflater = menuInflater
        inflater.inflate(R.menu.menu_items, menu)
        return true
    }

     override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        when (item!!.itemId) {
            R.id.done_item -> {
                if (currentPersonProfile == -1) {
                    menuSavePersonProfile()
                    Toast.makeText(this, "Saved Successfully", Toast.LENGTH_SHORT).show()
                } else {
                    menuUpdatePersonProfile()
                    Toast.makeText(this, "Updated Successfully", Toast.LENGTH_SHORT).show()
                }
                finish()
            }
            R.id.delete_item -> {
                menuDeletePersonProfile()
                Toast.makeText(this, "Deleted Successfully", Toast.LENGTH_SHORT).show()
                finish()
            }
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onPrepareOptionsMenu(menu: Menu): Boolean {
        super.onPrepareOptionsMenu(menu)
        if (currentPersonProfile == -1) {
            menu.findItem(R.id.delete_item).isVisible = false
        }
        return true
    }

    private fun menuSavePersonProfile() {
        var nameContact = et_name.text.toString()
        var numberContact = et_age.text.toString()
        var contact = PersonProfile(0, nameContact, numberContact)
        personProfileViewModel!!.addersonProfile(contact)
    }

    private fun menuDeletePersonProfile() {
        personProfileDAO!!.deletePersonProfiles(personProfile!!)
    }

    private fun menuUpdatePersonProfile() {
        var nameContact = et_name.text.toString()
        var numberContact = et_age.text.toString()
        var contact = PersonProfile(personProfile!!.idPerson, nameContact, numberContact)
        personProfileDAO!!.updatePersonProfiles(contact)
    }

}

//MainActivity.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package com.harshalbenake.kotlinroomlivedata.ui

import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.content.Intent
import android.os.Bundle
import android.support.design.widget.FloatingActionButton
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.Menu
import android.view.MenuItem
import com.harshalbenake.kotlinroomlivedata.R
import com.harshalbenake.kotlinroomlivedata.adapter.PersonProfileAdapter
import com.harshalbenake.kotlinroomlivedata.data.model.PersonProfile
import com.harshalbenake.kotlinroomlivedata.data.PersonProfileDb
import com.harshalbenake.kotlinroomlivedata.viewmodel.PersonProfileViewModel

class MainActivity : AppCompatActivity(), PersonProfileAdapter.OnItemClickListener {

    private var personProfileRecyclerView: RecyclerView? = null
    private var personProfileAdapter: PersonProfileAdapter? = null
    private var personProfileViewModel: PersonProfileViewModel? = null
    private var personProfileDB: PersonProfileDb? = null
    private var fab:FloatingActionButton?= null

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

        initLayout()

        personProfileRecyclerView!!.layoutManager = LinearLayoutManager(this)
        personProfileRecyclerView!!.adapter = personProfileAdapter

        personProfileViewModel!!.getListPersonProfiles().observe(this, Observer { personprofile ->
            personProfileAdapter!!.addContacts(personprofile!!)
        })
        fab!!.setOnClickListener {
            var intent = Intent(applicationContext, AddPersonActivity::class.java)
            startActivity(intent)
        }
    }

    /**
     * init Layout
     */
    fun initLayout(){
        personProfileRecyclerView = findViewById(R.id.recycler_view)
        fab = findViewById(R.id.fab)
        personProfileDB = PersonProfileDb.getDataBase(this)
        personProfileAdapter = PersonProfileAdapter(arrayListOf(), this)
        personProfileViewModel = ViewModelProviders.of(this).get(PersonProfileViewModel::class.java)

    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_main, menu)
        return true
    }

   override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.delete_all_items -> {
                menuDeleteAllPersonProfiles()
            }
        }
        return super.onOptionsItemSelected(item)
    }

    /**
     * menu deletes All Person Profiles
     */
    private fun menuDeleteAllPersonProfiles() {
        personProfileDB!!.personProfileDAO().deleteAllPersonProfiles()
    }
    override fun onItemClick(personProfile: PersonProfile) {
        var intent = Intent(applicationContext, AddPersonActivity::class.java)
        intent.putExtra("idPerson", personProfile.idPerson)
        startActivity(intent)
    }
}

Sunday, 14 October 2018

HB Blog 160: Listview Using DataBinding In Kotlin Language.

Hello guys, we have seen Listview using Kotlin Language in my old posts. You can recall using below link,
HB Blog 157: Listview In Android Using Kotlin.

Also, we saw Databinding library that is part of Jetpack Architecture in my previous blog post, 
HB Blog 159: Jetpack Architecture: - DataBinding.

In this tutorial, let us build listview using databinding in Kotlin language.
Refer the below link for complete sample code:-

Download Sample Code

Have a look on few code snippets,

//build.gradle
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 26
    buildToolsVersion "27.0.0"
    defaultConfig {
        applicationId "com.harshalbenake.kotlindatabindinglist"
        minSdkVersion 16
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    dataBinding {
        enabled true
    }
}

repositories {
    mavenCentral()
}
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:support-v4:26.1.0'
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:+"
    implementation 'com.android.support:recyclerview-v7:26.1.0'
    kapt "com.android.databinding:compiler:3.0.0"
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:+"
}

//rowitempersonprofile.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="personprofile"
            type="com.harshalbenake.kotlindatabindinglist.Model.PersonProfile" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:padding="16dp"
        android:layout_height="wrap_content"
        android:background="@android:drawable/alert_light_frame"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:textColor="@android:color/black"
            android:text="@{personprofile.name,default=name}" />

        <TextView
            android:id="@+id/tv_email"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{personprofile.email,default=email}" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{Integer.toString(personprofile.age),default=0}" />
    </LinearLayout>
</layout>

//PersonProfile.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.harshalbenake.kotlindatabindinglist.Model

/**
 * Used as a layout variable to provide static properties name, emails and age
 */
data class PersonProfile(
        val name: String,
        val email: String,
        val age: Int
)

//PersonProfileAdapter.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.harshalbenake.kotlindatabindinglist.Adapters

import android.databinding.DataBindingUtil
import android.databinding.ViewDataBinding
import android.graphics.Color
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import com.harshalbenake.kotlindatabindinglist.BR
import com.harshalbenake.kotlindatabindinglist.Model.PersonProfile
import com.harshalbenake.kotlindatabindinglist.R
import kotlinx.android.synthetic.main.rowitempersonprofile.view.*

class PersonProfileAdapter(val locallist: List<PersonProfile>) : RecyclerView.Adapter<ViewHolder>() {
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(locallist[position])
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        val binding: ViewDataBinding = DataBindingUtil.inflate(layoutInflater, R.layout.rowitempersonprofile, parent, false)
        binding.root.tv_email.setTextColor(Color.GRAY)
        return ViewHolder(binding)
    }

    override fun getItemCount(): Int = locallist.size
}

class ViewHolder(val binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root) {
    fun bind(personprofile: PersonProfile) {
        binding.setVariable(BR.personprofile, personprofile)
        binding.executePendingBindings()
    }
}

//MainActivity.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.harshalbenake.kotlindatabindinglist

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import com.harshalbenake.kotlindatabindinglist.Adapters.PersonProfileAdapter
import com.harshalbenake.kotlindatabindinglist.Model.PersonProfile

class MainActivity : AppCompatActivity() {

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

        //array variable initialized
        var listItems = arrayListOf<PersonProfile>()
        //arraylist item added
        for (i in 0..10) {
            listItems.add(PersonProfile("Harshal Benake " + i, "harshalbenake" + i + "@gmail.com", 28 + i))
        }

        val recyclerView = findViewById<RecyclerView>(R.id.rv_personprofile)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = PersonProfileAdapter(listItems)
    }
}

Saturday, 14 July 2018

HB Blog 157: Listview In Android Using Kotlin.

Kotlin is now an official language on Android. It's expressive, concise, and powerful. Best of all, it's interoperable with our existing Android languages and runtime.

Basically, it is not very hard to write a code in Kotlin language but, we need to start from class day 1.
Lets say, for getting started in kotlin you can refer link, Get Started with Kotlin on Android
There are few syntax to be adopted and file format as .kt instead of .java.

In this tutorial, I will show how to create a listview with custom adapter in Kotlin Android Application,
Refer the below link for complete sample code:-

Download Sample Code

Have a look on few code snippets,

//MainActivity.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package com.harshalbenake.koltinlist

import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.EditText
import android.widget.ListView
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*

/**
 * Main Activity
 */
class MainActivity : AppCompatActivity() {
    //array variable initialized
    var listItems = arrayListOf()
    //listview initialized
    private lateinit var lv_nameslist: ListView

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

        //smartcast - textview appearance changed without findViewById
        tv_name.text = "Enter name for adding to list"
        tv_name.setTextColor(Color.parseColor("#006500"))
        tv_name.textSize = 20F

        //editext variable using findViewById
        val et_name = findViewById(R.id.et_name)

        lv_nameslist = findViewById(R.id.lv_nameslist)

        //arraylist item added
        listItems.add("harshalbenake1")
        listItems.add("harshalbenake2")
        listItems.add("harshalbenake3")

        //variable value initialized and added to list
        var newName = "harshalbenake4"
        newName = "harshalbenake5"
        listItems.add(newName)

        //adapter set
        setAdapter(listItems)

        //button onclick event
        bt_add.setOnClickListener() {
            //methods called to add name
            addName("harshalbenake6")
            addName(et_name.text.toString())
        }

        //listview onitemclick event
        lv_nameslist.setOnItemClickListener { parent, view, position, id ->
            //item value retrived from positon
            var strName = parent.getItemAtPosition(position) as String
            //toast display
            Toast.makeText(this,strName,Toast.LENGTH_SHORT).show()
            //data passed to another activity
            val intent=Intent(this,DetailActivity::class.java)
            intent.putExtra("strNamePass", strName)
            startActivity(intent);
        }

    }

    override fun onPause() {
        super.onPause()
        //lifecycle method override
        println("onPause called")
    }

    /**
     * add Name
     */
    fun addName(strString: String) {
        //empty value check
        if(strString!="") {
            listItems.add(strString)
            setAdapter(listItems)
        }else{
            Toast.makeText(this,"No Name Added",Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * set Adapter
     */
    fun setAdapter(items: ArrayList) {
        //CustomBaseAdapter class parameterized constructor called
        var adapter = CustomBaseAdapter(items, this)
        //adapter set to listview
        lv_nameslist.adapter = adapter
    }
}

//CustomBaseAdapter.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.harshalbenake.koltinlist

import android.content.Context
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView

/**
 * Custom Base Adapter
 */
class CustomBaseAdapter(list: ArrayList, context: Context) : BaseAdapter() {
    //LayoutInflater initialized
    val mInflater: LayoutInflater = LayoutInflater.from(context)
    //list passed from mainactivity copyied to locallist
    var localList = list

    override fun getCount(): Int {
        return localList.size
    }

    override fun getItem(position: Int): Any {
        return localList[position]
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View? {
        val view: View?
        val viewHolder: ViewHolder
        if (convertView == null) {
            view = mInflater.inflate(R.layout.rowitem_name, parent, false)
            viewHolder = ViewHolder(view)
            view?.tag = viewHolder
        } else {
            view = convertView
            viewHolder = view.tag as ViewHolder
        }

        viewHolder.tv_rowitemname.setTextColor(Color.parseColor("#654657"))
        viewHolder.tv_rowitemname.textSize = 20F
        viewHolder.tv_rowitemname.text = localList.get(position).toString()
        return view
    }

    /**
     * View Holder class
     */
    private class ViewHolder(row: View) {
        var tv_rowitemname: TextView
        //view initialized using findViewById
        init {
            this.tv_rowitemname = row.findViewById(R.id.tv_rowitemname)
        }
    }
}

//DetailActivity.kt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package com.harshalbenake.koltinlist

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_detail.*

/**
 * Detail Activity class
 */
class DetailActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_detail)
        //intent data extracted
        var strName= intent.getStringExtra("strNamePass")
        tv_detailname.text=strName
    }
}