Skip to main content

android kotlin - Room boolean column example

MainActivity.kt

package com.example.roomexamples

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.method.ScrollingMovementMethod
import android.widget.TextView
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.toolbox.JsonArrayRequest
import com.android.volley.toolbox.Volley
import kotlinx.android.synthetic.main.activity_main.*
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.toast
import org.jetbrains.anko.uiThread
import java.text.DateFormat
import java.util.*


class MainActivity : AppCompatActivity() {

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

        val room = RoomSingleton.getInstance(this)
        textView.movementMethod = ScrollingMovementMethod()

        // Insert some products in database
        btnInsert.setOnClickListener {
            val url = "https://tradeogre.com/api/v1/history/BTC-KRB"

            val request = JsonArrayRequest(
                Request.Method.GET,
                url,
                null,
                Response.Listener{
                    val list = arrayListOf<History>()

                    for (i in 0 until it.length()){
                        val obj =  it.getJSONObject(i)

                        val timeMillis = obj.getLong("date")
                        val type = obj.getString("type")
                        val price = obj.getString("price").toBigDecimal()
                        val quantity = obj.getString("quantity").toBigDecimal()

                        var isSell = true
                        if (type.equals("buy")) isSell = false

                        val history = History(null,Date(timeMillis),isSell,price,quantity)
                        list.add(history)
                    }

                    doAsync {
                        room.historyDao().insertAll(list)
                        uiThread {
                            toast("done")
                        }
                    }


                },Response.ErrorListener {
                    toast(it.toString())
                }
            )

            // Add the request to the RequestQueue.
            Volley.newRequestQueue(this).add(request)
        }

        btnSell.setOnClickListener {
            doAsync {
                val list = room.historyDao().allSale()

                uiThread {
                    displayResult(list,textView)
                }
            }
        }


        btnBuy.setOnClickListener {
            doAsync {
                // Pass boolean parameter to room query
                val list = room.historyDao().allByQuery(false)

                uiThread {
                    displayResult(list,textView)
                }
            }
        }
    }
}


fun displayResult(list:List<History>,textView:TextView){
    textView.text = ""
    list.forEach {
        textView.append(it.date.medium)
        if (it.isSell){
            textView.append("\nType: Sell")

        }else{
            textView.append("\nType: Buy")
        }
        textView.append("\nPrice: " + it.price)
        textView.append("\nQuantity: " + it.quantity + "\n\n")
    }
}


// Extension property to format date
val Date.medium:String
    get() = DateFormat.getDateInstance(DateFormat.MEDIUM).format(this)
activity_main.xml

<?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">
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="32dp"
        android:layout_marginEnd="8dp"
        android:text=""
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnInsert"
        />
    <Button
        android:id="@+id/btnInsert"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="Insert"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
    <Button
        android:id="@+id/btnSell"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="Sell"
        app:layout_constraintStart_toEndOf="@+id/btnInsert"
        app:layout_constraintTop_toTopOf="parent" 
        />
    <Button
        android:id="@+id/btnBuy"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="Buy"
        app:layout_constraintStart_toEndOf="@+id/btnSell"
        app:layout_constraintTop_toTopOf="parent"
        />
</androidx.constraintlayout.widget.ConstraintLayout>
RoomSingleton.kt

package com.example.roomexamples

import android.content.Context
import androidx.room.*

@Database(entities = arrayOf(History::class), version = 1, exportSchema = false)
@TypeConverters(Converter::class)

abstract class RoomSingleton : RoomDatabase(){
    abstract fun historyDao(): HistoryDao
    companion object{
        private var INSTANCE: RoomSingleton? = null
        fun getInstance(context: Context): RoomSingleton{
            if (INSTANCE == null){
                INSTANCE = Room.databaseBuilder(
                    context,
                    RoomSingleton::class.java,
                    "roomdb")
                    .build()
            }
            return INSTANCE as RoomSingleton
        }
    }
}
RoomDao.kt

package com.example.roomexamples

import androidx.room.*
import java.math.BigDecimal
import java.util.*


@Entity(tableName = "historyTbl")
data class History(
    @PrimaryKey(autoGenerate = true)
    var id:Long?=null,
    var date:Date,
    var isSell:Boolean,
    var price:BigDecimal,
    var quantity:BigDecimal
)


@Dao
interface HistoryDao {

    // SQLite have no boolean data type
    // Room maps boolean data to an INTEGER column
    // Room mapping true to 1 and false to 0
    @Query("SELECT * FROM historyTbl WHERE isSell = 1 ORDER BY date DESC")
    fun allSale():List<History>

    @Query("SELECT * FROM historyTbl WHERE isSell =:isSell ORDER BY date DESC")
    fun allByQuery(isSell: Boolean):List<History>

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(history:History)

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insertAll(histories:List<History>)
}
Converter.kt

package com.example.roomexamples

import androidx.room.TypeConverter
import java.math.BigDecimal
import java.util.*

class Converter{
    companion object{
        @TypeConverter
        @JvmStatic
        fun fromBigDecimal(value:BigDecimal):String{
            return value.toString()
        }

        @TypeConverter
        @JvmStatic
        fun toBigDecimal(value:String):BigDecimal{
            return value.toBigDecimal()
        }

        @TypeConverter
        @JvmStatic
        fun toDate(value:Long):Date{
            //If your result always returns 1970, then comment this line
            //val date =  Date(value)

            //If your result always returns 1970, then uncomment this line
            val date = Date(value*1000L)

            return date
        }

        @TypeConverter
        @JvmStatic
        fun fromDate(date:Date):Long{
            return date.time
        }
    }
}
app build.gradle [required]

apply plugin: 'kotlin-kapt'

dependencies {
    // Room
    def room_version = "2.2.0-alpha01"
    implementation "androidx.room:room-runtime:$room_version"
    kapt 'androidx.room:room-compiler:2.2.0-alpha01'

    // Anko Commons
    implementation "org.jetbrains.anko:anko-commons:0.10.8"

    // Volley network library
    implementation 'com.android.volley:volley:1.1.1'
}

Popular posts from this blog

Restricting Jetpack Compose TextField to Numeric Input Only

Jetpack Compose has revolutionized Android development with its declarative approach, enabling developers to build modern, responsive UIs more efficiently. Among the many components provided by Compose, TextField is a critical building block for user input. However, ensuring that a TextField accepts only numeric input can pose challenges, especially when considering edge cases like empty fields, invalid characters, or localization nuances. In this blog post, we'll explore how to restrict a Jetpack Compose TextField to numeric input only, discussing both basic and advanced implementations. Why Restricting Input Matters Restricting user input to numeric values is a common requirement in apps dealing with forms, payment entries, age verifications, or any data where only numbers are valid. Properly validating input at the UI level enhances user experience, reduces backend validation overhead, and minimizes errors during data processing. Compose provides the flexibility to implement ...

jetpack compose - TextField remove underline

Compose TextField Remove Underline The TextField is the text input widget of android jetpack compose library. TextField is an equivalent widget of the android view system’s EditText widget. TextField is used to enter and modify text. The following jetpack compose tutorial will demonstrate to us how we can remove (actually hide) the underline from a TextField widget in an android application. We have to apply a simple trick to remove (hide) the underline from the TextField. The TextField constructor’s ‘colors’ argument allows us to set or change colors for TextField’s various components such as text color, cursor color, label color, error color, background color, focused and unfocused indicator color, etc. Jetpack developers can pass a TextFieldDefaults.textFieldColors() function with arguments value for the TextField ‘colors’ argument. There are many arguments for this ‘TextFieldDefaults.textFieldColors()’function such as textColor, disabledTextColor, backgroundColor, cursorC...

jetpack compose - Image clickable

Compose Image Clickable The Image widget allows android developers to display an image object to the app user interface using the jetpack compose library. Android app developers can show image objects to the Image widget from various sources such as painter resources, vector resources, bitmap, etc. Image is a very essential component of the jetpack compose library. Android app developers can change many properties of an Image widget by its modifiers such as size, shape, etc. We also can specify the Image object scaling algorithm, content description, etc. But how can we set a click event to an Image widget in a jetpack compose application? There is no built-in property/parameter/argument to set up an onClick event directly to the Image widget. This android application development tutorial will demonstrate to us how we can add a click event to the Image widget and make it clickable. Click event of a widget allow app users to execute a task such as showing a toast message by cli...