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)
    }
}

Friday 14 September 2018

HB Blog 159: Jetpack Architecture: - DataBinding.

The Data Binding Library is a support library that allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically.

The expression language allows you to write expressions that connect variables to the views in the layout. The Data Binding Library automatically generates the classes required to bind the views in the layout with your data objects. The library provides features such as imports, variables, and includes that you can use in your layouts.

These features of the library coexist seamlessly with your existing layouts. For example, the binding variables that can be used in expressions are defined inside a data element that is a sibling of the UI layout's root element.
The Data Binding Library generates binding classes that are used to access the layout's variables and views

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
apply plugin: 'com.android.application'

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

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation('com.android.support:support-v4:27.1.0')
    implementation 'com.android.support:appcompat-v7:27.1.0'

}

//activity_main.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
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <import type="android.view.View"/>
        <import type="com.harshalbenake.databinding.MainActivity.Utils"/>
        <variable
            name="dataPojo"
            type="com.harshalbenake.databinding.DataPojo" />
        <variable name="presenter" type="com.harshalbenake.databinding.Presenter" />

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="16dp"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{Utils.appendSurname(dataPojo.name),default=nameXML}" />

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

        <Button
            android:layout_width="wrap_content"
            android:text="HBBlogs"
            android:layout_gravity="center"
            android:layout_height="wrap_content"
            android:onClick="@{(view) -> presenter.onSaveClick(view,dataPojo)}" />
    </LinearLayout>
</layout>

//DataPojo.java 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package com.harshalbenake.databinding;

public class DataPojo{
    private final String name;
    private final String email;

    public DataPojo(String name, String email) {
        this.name = name;
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public String getEmail() {
        return email;
    }
}

//MainActivity.java 
 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
package com.harshalbenake.databinding;

import android.content.Context;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;

import com.harshalbenake.databinding.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity implements Presenter{
    private int mCounter=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Inflate the content view (replacing `setContentView`)
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        //adding data to pojoobject
        DataPojo dataPojo=new DataPojo("Harshal","harshalbenake@gmail.com");
        //setting datapojo to binding
        binding.setDataPojo(dataPojo);
        //set listner to9 binding
        binding.setPresenter(this);
        //setting textview appearance without creating textview object
        binding.tvName.setTextSize(25f);
    }

    @Override
    public void onSaveClick(View view, DataPojo dataPojo) {
        mCounter=mCounter+1;
        Toast.makeText(this,"Name: "+dataPojo.getName()+"\nEmail: "+dataPojo.getEmail()+"\n"+mCounter,Toast.LENGTH_SHORT).show();
    }


    /**
     * Inner static class Utils
     */
    public static class Utils {
        Context mContext;
        public Utils(Context context) {
            this.mContext=context;
        }

        /**
         * appends Surname
         * @param strText
         * @return
         */
        public static String appendSurname(String strText){
            return strText+" Benake";
        }
    }

}

Tuesday 14 August 2018

HB Blog 158: Jetpack Architecture: - Work Manager.

The WorkManager API makes it easy to specify deferrable, asynchronous tasks and when they should run. These APIs let you create a task and hand it off to WorkManager to run immediately or at an appropriate time.

It is intended for tasks that require a guarantee that the system will run them even if the app exits, like uploading app data to a server. It is not intended for in-process background work that can safely be terminated if the app process goes away; for situations like that, we recommend using ThreadPools.

It chooses an appropriate way to schedule a background task--depending on the device API level and included dependencies, which might use JobScheduler, Firebase JobDispatcher, or AlarmManager. You don't need to write device logic to figure out what capabilities the device has and choose an appropriate API; instead, you can just hand your task off to WorkManager and let it choose the best option.

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
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.0'
    def work_version = "1.0.0-alpha04"
    implementation "android.arch.work:work-runtime:$work_version" // use -ktx for Kotlin
    // optional - Firebase JobDispatcher support
    implementation "android.arch.work:work-firebase:$work_version"
}

//BasicWorker.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package com.harshalbenake.workmanager.worker;

import android.support.annotation.NonNull;
import androidx.work.Worker;

public class BasicWorker extends Worker{

    @Override
    public Result doWork() {
        printBasicWork();
        // Indicate success or failure with your return value:
        return Result.SUCCESS;
    }

    private void printBasicWork() {
        System.out.println("harshalbenake printBasicWork");
    }
}

//PeriodicWorker.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package com.harshalbenake.workmanager.worker;

import android.support.annotation.NonNull;
import androidx.work.Worker;

public class PeriodicWorker extends Worker{
 
    @Override
    public Result doWork() {
        printPeriodicWork();
        // Indicate success or failure with your return value:
        return Result.SUCCESS;
    }

    private void printPeriodicWork() {
        System.out.println("harshalbenake printPeriodicWork");
    }
}