SQLite CRUD Examples
Kotlin Android SQLite database simple CRUD example tutorial
This is an SQLite tutorial for android using Kotlin programming language. We see how to perforom operations like inserting, updating, reading and deleting data.
Example 1: Kotlin Android Beginners SQLite CRUD
This tutorial is really suitable for newbies who just want to learn how to perform operations against SQLite database. We are seeing how to add data to sqlite from edittexts on button click.
The user also utilizes the same edittexts for updating data. However for this to happen you have to supply the ud. The id isn't necessary while inserting data. This is because it gets auto generated and autoincremented by SQLite datbase itself.
To delete you also have to supply the id. This identifies the row to be deleted.
Demo
Here's the gif demo of the project:
Layouts
We have only a single layout:
(a). activitt_main.xml
Our mainactivity's layout. It will contained several edittexts and buttons which will allow user to perform CRUD operations.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android_orientation="vertical"
android_layout_width="match_parent"
android_layout_height="match_parent"
tools_context=".MainActivity">
<LinearLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_orientation="horizontal">
<TextView
android_id="@+id/nameLabel"
android_layout_width="0dp"
android_layout_weight="1"
android_layout_height="wrap_content"
android_maxLines="1"
android_padding="5dp"
android_text="ID"
android_textColor="@color/colorAccent"
android_textAppearance="?android:attr/textAppearanceSmall"
android_textStyle="bold" />
<EditText
android_id="@+id/idTxt"
android_layout_width="0dp"
android_layout_weight="2"
android_layout_height="wrap_content"
android_ems="10"
android_inputType="number"
android_hint="ID" />
</LinearLayout>
<LinearLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_orientation="horizontal">
<TextView
android_layout_width="0dp"
android_layout_weight="1"
android_layout_height="wrap_content"
android_maxLines="1"
android_padding="5dp"
android_text="NAME: "
android_textColor="@color/colorAccent"
android_textAppearance="?android:attr/textAppearanceSmall"
android_textStyle="bold" />
<EditText
android_id="@+id/nameTxt"
android_layout_width="0dp"
android_layout_weight="2"
android_layout_height="wrap_content"
android_ems="10"
android_inputType="textPersonName"
android_hint="NAME" />
</LinearLayout>
<LinearLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_orientation="horizontal">
<TextView
android_layout_width="0dp"
android_layout_weight="1"
android_layout_height="wrap_content"
android_maxLines="1"
android_padding="5dp"
android_text="GALAXY: "
android_textColor="@color/colorAccent"
android_textAppearance="?android:attr/textAppearanceSmall"
android_textStyle="bold" />
<EditText
android_id="@+id/galaxyTxt"
android_layout_width="0dp"
android_layout_weight="2"
android_layout_height="wrap_content"
android_ems="10"
android_inputType="textPersonName"
android_hint="GALAXY" />
</LinearLayout>
<LinearLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_orientation="horizontal">
<TextView
android_layout_width="0dp"
android_layout_weight="1"
android_layout_height="wrap_content"
android_maxLines="1"
android_padding="5dp"
android_text="TYPE: "
android_textColor="@color/colorAccent"
android_textAppearance="?android:attr/textAppearanceSmall"
android_textStyle="bold" />
<EditText
android_id="@+id/typeTxt"
android_layout_width="0dp"
android_layout_weight="2"
android_layout_height="wrap_content"
android_ems="10"
android_inputType="textCapWords"
android_hint="STAR TYPE" />
</LinearLayout>
<LinearLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_orientation="horizontal">
<Button
android_id="@+id/insertBtn"
android_layout_width="0dp"
android_layout_weight="1"
android_layout_height="wrap_content"
android_text="INSERT" />
<Button
android_id="@+id/updateBtn"
android_layout_width="0dp"
android_layout_weight="1"
android_layout_height="wrap_content"
android_text="UPDATE" />
</LinearLayout>
<LinearLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_orientation="horizontal">
<Button
android_id="@+id/deleteBtn"
android_layout_width="0dp"
android_layout_weight="1"
android_layout_height="wrap_content"
android_text="DELETE" />
<Button
android_id="@+id/viewBtn"
android_layout_width="0dp"
android_layout_weight="1"
android_layout_height="wrap_content"
android_text="VIEW ALL" />
</LinearLayout>
</LinearLayout>
Kotlin Code
We have two classes:
(a). DatabaseHelper.java
This class will allow us work with SQLite easily, allowing us to perform CRUD operations like adding, deleting, updating and deleting data.
package info.camposha.kotlinsqlite
import android.content.Context
import android.database.sqlite.SQLiteOpenHelper
import android.content.ContentValues
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
/**
* Let's start by creating our database CRUD helper class
* based on the SQLiteHelper.
*/
class DatabaseHelper(context: Context) :
SQLiteOpenHelper(context, DATABASE_NAME, null, 1) {
/**
* Our onCreate() method.
* Called when the database is created for the first time. This is
* where the creation of tables and the initial population of the tables
* should happen.
*/
override fun onCreate(db: SQLiteDatabase) {
db.execSQL("CREATE TABLE $TABLE_NAME (ID INTEGER PRIMARY KEY " +
"AUTOINCREMENT,NAME TEXT,GALAXY TEXT,TYPE TEXT)")
}
/**
* Let's create Our onUpgrade method
* Called when the database needs to be upgraded. The implementation should
* use this method to drop tables, add tables, or do anything else it needs
* to upgrade to the new schema version.
*/
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME)
onCreate(db)
}
/**
* Let's create our insertData() method.
* It Will insert data to SQLIte database.
*/
fun insertData(name: String, surname: String, marks: String) {
val db = this.writableDatabase
val contentValues = ContentValues()
contentValues.put(COL_2, name)
contentValues.put(COL_3, surname)
contentValues.put(COL_4, marks)
db.insert(TABLE_NAME, null, contentValues)
}
/**
* Let's create a method to update a row with new field values.
*/
fun updateData(id: String, name: String, surname: String, marks: String):
Boolean {
val db = this.writableDatabase
val contentValues = ContentValues()
contentValues.put(COL_1, id)
contentValues.put(COL_2, name)
contentValues.put(COL_3, surname)
contentValues.put(COL_4, marks)
db.update(TABLE_NAME, contentValues, "ID = ?", arrayOf(id))
return true
}
/**
* Let's create a function to delete a given row based on the id.
*/
fun deleteData(id : String) : Int {
val db = this.writableDatabase
return db.delete(TABLE_NAME,"ID = ?", arrayOf(id))
}
/**
* The below getter property will return a Cursor containing our dataset.
*/
val allData : Cursor
get() {
val db = this.writableDatabase
val res = db.rawQuery("SELECT * FROM " + TABLE_NAME, null)
return res
}
/**
* Let's create a companion object to hold our static fields.
* A Companion object is an object that is common to all instances of a given
* class.
*/
companion object {
val DATABASE_NAME = "stars.db"
val TABLE_NAME = "star_table"
val COL_1 = "ID"
val COL_2 = "NAME"
val COL_3 = "GALAXY"
val COL_4 = "TYPE"
}
}
//end
(b). MainActivity.java
The main activity is the entry point to our Kotlin app. We have cleanly commented the code for inline explanations.
package info.camposha.kotlinsqlite
import android.app.AlertDialog
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.View
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
//In Kotlin `var` is used to declare a mutable variable. On the other hand
//`internal` means a variable is visible within a given module.
internal var dbHelper = DatabaseHelper(this)
/**
* Let's create a function to show Toast message
*/
fun showToast(text: String){
Toast.makeText(this@MainActivity, text, Toast.LENGTH_LONG).show()
}
/**
* Let's create a function to show an alert dialog with data dialog.
*/
fun showDialog(title : String,Message : String){
val builder = AlertDialog.Builder(this)
builder.setCancelable(true)
builder.setTitle(title)
builder.setMessage(Message)
builder.show()
}
/**
* Let's create a method to clear our edittexts
*/
fun clearEditTexts(){
nameTxt.setText("")
galaxyTxt.setText("")
typeTxt.setText("")
idTxt.setText("")
}
/**
* Let's override our onCreate method.
*/
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
handleInserts()
handleUpdates()
handleDeletes()
handleViewing()
}
/**
* When our handleInserts button is clicked.
*/
fun handleInserts() {
insertBtn.setOnClickListener {
try {
dbHelper.insertData(nameTxt.text.toString(),galaxyTxt.text.toString(),
typeTxt.text.toString())
clearEditTexts()
}catch (e: Exception){
e.printStackTrace()
showToast(e.message.toString())
}
}
}
/**
* When our handleUpdates data button is clicked
*/
fun handleUpdates() {
updateBtn.setOnClickListener {
try {
val isUpdate = dbHelper.updateData(idTxt.text.toString(),
nameTxt.text.toString(),
galaxyTxt.text.toString(), typeTxt.text.toString())
if (isUpdate == true)
showToast("Data Updated Successfully")
else
showToast("Data Not Updated")
}catch (e: Exception){
e.printStackTrace()
showToast(e.message.toString())
}
}
}
/**
* When our handleDeletes button is clicked
*/
fun handleDeletes(){
deleteBtn.setOnClickListener {
try {
dbHelper.deleteData(idTxt.text.toString())
clearEditTexts()
}catch (e: Exception){
e.printStackTrace()
showToast(e.message.toString())
}
}
}
/**
* When our View All is clicked
*/
fun handleViewing() {
viewBtn.setOnClickListener(
View.OnClickListener {
val res = dbHelper.allData
if (res.count == 0) {
showDialog("Error", "No Data Found")
return@OnClickListener
}
val buffer = StringBuffer()
while (res.moveToNext()) {
buffer.append("ID :" + res.getString(0) + "n")
buffer.append("NAME :" + res.getString(1) + "n")
buffer.append("GALAXY :" + res.getString(2) + "n")
buffer.append("TYPE :" + res.getString(3) + "nn")
}
showDialog("Data Listing", buffer.toString())
}
)
}
}
//end
Download
You can download the full source code below or watch the video from the link provided.
No. | Location | Link |
---|---|---|
1. | GitHub | Direct Download |
2. | GitHub | Browse |
3. | YouTube | Video Tutorial |
4. | YouTube | ProgrammingWizards TV Channel |
Example 2: Kotlin Notepad App - SQLite CRUD, Search, Sort
Learn how to create a full Notepad app by implementing CRUD operations in SQLite database.
Step 1: Create Project
Start by creating an empty Android Studio
project.
Step 2: Dependencies
No external library is needed for this project.
Step 3: Create Menu
We will be performing some of the actions from the menu. This let's create menu inside our res/menu
folder. If you do not have the menu
folder then create it inside the res
directory:
menu/main_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_sort"
android:title="Sort"/>
<item
android:id="@+id/app_bar_search"
android:icon="@drawable/ic_search_black_24dp"
app:showAsAction="always"
android:title="Search"
app:actionViewClass="android.widget.SearchView" />
<item
android:id="@+id/addNote"
android:title="Add Note"
android:icon="@drawable/ic_note_add_black_24dp"
app:showAsAction="always"/>
</menu>
Step 4: Design Layouts
We will have the following layouts
(a). row.xml
A row for our listview:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="wrap_content"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="3dp"
app:cardElevation="3dp"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:gravity="end|bottom"
android:orientation="vertical">
<TextView
android:id="@+id/titleTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Title"
android:textColor="@color/colorPrimary"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/descTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="There may be a very long description of the note" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="2dp"
android:layout_marginBottom="3dp"
android:background="@color/colorPrimaryDark" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:orientation="horizontal">
<ImageButton
android:id="@+id/deleteBtn"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:background="@null"
android:scaleType="fitXY"
android:src="@drawable/ic_delete_black_24dp" />
<ImageButton
android:id="@+id/editBtn"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:background="@null"
android:scaleType="fitXY"
android:src="@drawable/ic_edit_black_24dp" />
<ImageButton
android:id="@+id/copyBtn"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:background="@null"
android:scaleType="fitXY"
android:src="@drawable/ic_content_copy_black_24dp" />
<ImageButton
android:id="@+id/shareBtn"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:background="@null"
android:scaleType="fitXY"
android:src="@drawable/ic_share_black_24dp" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
(b). activity_add_note.xml
The xml layout for the activity for adding our notes:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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=".AddNoteActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="3dp"
app:cardElevation="3dp"
android:layout_margin="5dp"
app:cardBackgroundColor="@color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/titleEt"
android:background="@null"
android:hint="Enter Title"
android:singleLine="true"
android:padding="10dp"
android:inputType="textCapSentences"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<EditText
android:id="@+id/descEt"
android:background="@null"
android:gravity="top"
android:hint="Enter Description..."
android:minHeight="100dp"
android:padding="10dp"
android:inputType="textCapSentences|textImeMultiLine"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<Button
android:id="@+id/addBtn"
style="@style/Base.Widget.AppCompat.Button.Colored"
android:text="Add"
android:layout_gravity="end"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="addFunc"/>
</LinearLayout>
</ScrollView>
(c). activity_main.xml
The layout for listing our notes. We include a listview:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/gray"
tools:context=".MainActivity">
<ListView
android:id="@+id/noteLv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
android:dividerHeight="1dp"/>
</LinearLayout>
Step 5: Create Model class
Create our Note
model class as follows:
Note.kt
class Note(noteID: Int, noteName: String, noteDes: String)
{
var noteID : Int? = noteID
var noteName : String? = noteName
var noteDes : String? = noteDes
}
Step 6: Create Database Manager
Create a class to manage our database:
DbManager.kt
This is the class that will contain our CRUD operations.
import android.app.DownloadManager
import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.database.sqlite.SQLiteQueryBuilder
import android.widget.Toast
class DbManager {
//database name
var dbName = "MyNotes"
//table name
var dbTable = "Notes"
//columns
var colID = "ID"
var colTitle = "Title"
var colDes = "Description"
//database version
var dbVersion = 1
//CREATE TABLE IF NOT EXISTS MyNotes (ID INTEGER PRIMARY KEY, title TEXT, Description TEXT)
val sqlCreateTable =
"CREATE TABLE IF NOT EXISTS "+dbTable+" ("+colID+" INTEGER PRIMARY KEY,"+ colTitle +" TEXT, "+colDes+" TEXT)"
var sqlDB: SQLiteDatabase? = null
constructor(context: Context)
{
var db = DatabaseHelperNotes(context)
sqlDB = db.writableDatabase
}
inner class DatabaseHelperNotes : SQLiteOpenHelper {
var context: Context? = null
constructor(context: Context) : super(context, dbName, null, dbVersion) {
this.context = context
}
override fun onCreate(db: SQLiteDatabase?) {
db!!.execSQL(sqlCreateTable)
Toast.makeText(this.context, "database created...", Toast.LENGTH_SHORT).show()
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
db!!.execSQL("Drop table if Exists" + dbTable)
}
}
fun insert(values : ContentValues) : Long
{
val ID = sqlDB!!.insert(dbTable,"", values)
return ID
}
fun Query(projection : Array<String>, selection : String, selectionArgs : Array<String>, sorOrder : String) : Cursor
{
val qb = SQLiteQueryBuilder()
qb.tables = dbTable
val cursor = qb.query(sqlDB, projection, selection, selectionArgs, null, null, sorOrder)
return cursor
}
fun delete(selection: String, selectionArgs: Array<String>) : Int
{
val count = sqlDB!!.delete(dbTable, selection, selectionArgs)
return count
}
fun update(values: ContentValues, selection: String, selectionArgs: Array<String>) : Int
{
val count = sqlDB!!.update(dbTable, values, selection, selectionArgs)
return count
}
}
Step 7: Create Activities
Create the following two activities:
(a). AddNoteActivity.kt
A class for adding notes
import android.content.ContentValues
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import com.example.notepadusingkotlin.DataBase.DbManager
import kotlinx.android.synthetic.main.activity_add_note.*
import kotlinx.android.synthetic.main.row.*
import java.lang.Exception
class AddNoteActivity : AppCompatActivity() {
val dbTable = "Notes"
var id = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_note)
try {
val bundle : Bundle? = intent.extras
id = bundle!!.getInt("ID", 0)
if (id!=0)
{
//update note
//change actionbar title
supportActionBar!!.title = "Update Note"
//change button text
addBtn.text = "Update"
titleEt.setText(bundle.getString("name"))
descEt.setText(bundle.getString("des"))
}
}catch (ex : Exception){
}
}
fun addFunc(view: View)
{
var dbManager = DbManager(this)
var values = ContentValues()
values.put("Title", titleEt.text.toString())
values.put("Description", descEt.text.toString())
if (id == 0)
{
val ID = dbManager.insert(values)
if (ID>0)
{
Toast.makeText(this, "Note is added", Toast.LENGTH_SHORT).show()
finish()
}
else
{
Toast.makeText(this, "Error adding note...", Toast.LENGTH_SHORT).show()
}
}
else
{
var selectionArgs = arrayOf(id.toString())
val ID = dbManager.update(values, "ID=?", selectionArgs)
if (ID>0)
{
Toast.makeText(this, "Note is updated", Toast.LENGTH_SHORT).show()
finish()
}
else
{
Toast.makeText(this, "Error updating note...", Toast.LENGTH_SHORT).show()
}
}
}
}
(b). MainActivity.kt
The MainActivity class.
Will also render or list our notes:
import android.app.AlertDialog
import android.app.SearchManager
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.ClipboardManager
import android.view.*
import android.widget.BaseAdapter
import android.widget.SearchView
import android.widget.Toast
import com.example.notepadusingkotlin.DataBase.DbManager
import com.example.notepadusingkotlin.Model.Note
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.row.view.*
class MainActivity : AppCompatActivity() {
var listNotes = ArrayList<Note>()
//shared preference
var mSharedPref : SharedPreferences? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mSharedPref = this.getSharedPreferences("My_Data", Context.MODE_PRIVATE)
//load sorting technique as selected before, default setting will be newest
val mSorting = mSharedPref!!.getString("Sort", "newest")
when(mSorting)
{
"newest" -> LoadQueryNewest("%")
"oldest" -> LoadQueryOldest("%")
"ascending" -> LoadQueryAscending("%")
"descending" -> LoadQueryDescending("%")
}
}
override fun onResume() {
super.onResume()
//load sorting technique as selected before, default setting will be newest
val mSorting = mSharedPref!!.getString("Sort", "newest")
when(mSorting)
{
"newest" -> LoadQueryNewest("%")
"oldest" -> LoadQueryOldest("%")
"ascending" -> LoadQueryAscending("%")
"descending" -> LoadQueryDescending("%")
}
}
private fun LoadQueryAscending(title: String) {
var dbManager = DbManager(this)
val projections = arrayOf("ID", "Title", "Description")
val selectionArgs = arrayOf(title)
//sort by title
val cursor = dbManager.Query(projections, "Title like ?", selectionArgs, "Title")
listNotes.clear()
//ascending
if (cursor.moveToFirst()) {
do {
val ID = cursor.getInt(cursor.getColumnIndex("ID"))
val Title = cursor.getString(cursor.getColumnIndex("Title"))
val Description = cursor.getString(cursor.getColumnIndex("Description"))
listNotes.add(Note(ID, Title, Description))
} while (cursor.moveToNext())
}
//adapter
var myNotesAdapter = MyNotesAdapter(this, listNotes)
//set adapter
noteLv.adapter = myNotesAdapter
//get total number of tasks from List
val total = noteLv.count
//actionbar
val mActionBar = supportActionBar
if (mActionBar != null)
{
//set to actionbar as subtitle of actionbar
mActionBar.subtitle = "You have $total note(s) in list..."
}
}
private fun LoadQueryDescending(title: String) {
var dbManager = DbManager(this)
val projections = arrayOf("ID", "Title", "Description")
val selectionArgs = arrayOf(title)
//sort by title
val cursor = dbManager.Query(projections, "Title like ?", selectionArgs, "Title")
listNotes.clear()
//descending
if (cursor.moveToLast()) {
do {
val ID = cursor.getInt(cursor.getColumnIndex("ID"))
val Title = cursor.getString(cursor.getColumnIndex("Title"))
val Description = cursor.getString(cursor.getColumnIndex("Description"))
listNotes.add(Note(ID, Title, Description))
} while (cursor.moveToPrevious())
}
//adapter
var myNotesAdapter = MyNotesAdapter(this, listNotes)
//set adapter
noteLv.adapter = myNotesAdapter
//get total number of tasks from List
val total = noteLv.count
//actionbar
val mActionBar = supportActionBar
if (mActionBar != null)
{
//set to actionbar as subtitle of actionbar
mActionBar.subtitle = "You have $total note(s) in list..."
}
}
private fun LoadQueryNewest(title: String) {
var dbManager = DbManager(this)
val projections = arrayOf("ID", "Title", "Description")
val selectionArgs = arrayOf(title)
//sort by ID
val cursor = dbManager.Query(projections, "ID like ?", selectionArgs, "ID")
listNotes.clear()
//Newest first(the record will be entered at the bottom of previous records and has larger ID then previous records)
if (cursor.moveToLast()) {
do {
val ID = cursor.getInt(cursor.getColumnIndex("ID"))
val Title = cursor.getString(cursor.getColumnIndex("Title"))
val Description = cursor.getString(cursor.getColumnIndex("Description"))
listNotes.add(Note(ID, Title, Description))
} while (cursor.moveToPrevious())
}
//adapter
var myNotesAdapter = MyNotesAdapter(this, listNotes)
//set adapter
noteLv.adapter = myNotesAdapter
//get total number of tasks from List
val total = noteLv.count
//actionbar
val mActionBar = supportActionBar
if (mActionBar != null)
{
//set to actionbar as subtitle of actionbar
mActionBar.subtitle = "You have $total note(s) in list..."
}
}
private fun LoadQueryOldest(title: String) {
var dbManager = DbManager(this)
val projections = arrayOf("ID", "Title", "Description")
val selectionArgs = arrayOf(title)
//sort by ID
val cursor = dbManager.Query(projections, "ID like ?", selectionArgs, "ID")
listNotes.clear()
//oldest first(the record will be entered at the bottom of previous records and has larger ID then previous records, so lesser the ID is the oldest the record is)
if (cursor.moveToFirst()) {
do {
val ID = cursor.getInt(cursor.getColumnIndex("ID"))
val Title = cursor.getString(cursor.getColumnIndex("Title"))
val Description = cursor.getString(cursor.getColumnIndex("Description"))
listNotes.add(Note(ID, Title, Description))
} while (cursor.moveToNext())
}
//adapter
var myNotesAdapter = MyNotesAdapter(this, listNotes)
//set adapter
noteLv.adapter = myNotesAdapter
//get total number of tasks from List
val total = noteLv.count
//actionbar
val mActionBar = supportActionBar
if (mActionBar != null)
{
//set to actionbar as subtitle of actionbar
mActionBar.subtitle = "You have $total note(s) in list..."
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.main_menu, menu)
val sv:SearchView = menu!!.findItem(R.id.app_bar_search).actionView as SearchView
val sm = getSystemService(Context.SEARCH_SERVICE) as SearchManager
sv.setSearchableInfo(sm.getSearchableInfo(componentName))
sv.setOnQueryTextListener(object : SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(query: String?): Boolean {
LoadQueryAscending("%"+query+"%")
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
LoadQueryAscending("%"+newText+"%")
return false
}
})
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item != null)
{
when(item.itemId)
{
R.id.addNote ->
{
startActivity(Intent(this, AddNoteActivity::class.java))
}
R.id.action_sort ->
{
//show sorting dialog
showSortDialog()
}
}
}
return super.onOptionsItemSelected(item)
}
private fun showSortDialog() {
val sortOption = arrayOf("Newest", "Older", "Title(Ascending)", "Title(Descending)")
val mBuilder = AlertDialog.Builder(this)
mBuilder.setTitle("Sort by")
mBuilder.setIcon(R.drawable.ic_sort_black_24dp)
mBuilder.setSingleChoiceItems(sortOption, -1)
{
dialogInterface, i ->
if (i==0)
{
//newest first
Toast.makeText(this,"Newest",Toast.LENGTH_SHORT).show()
val editor = mSharedPref!!.edit()
editor.putString("Sort", "newest")
editor.apply()
LoadQueryNewest("%")
}
if (i==1)
{
//older first
Toast.makeText(this,"Oldest",Toast.LENGTH_SHORT).show()
val editor = mSharedPref!!.edit()
editor.putString("Sort", "oldest")
editor.apply()
LoadQueryOldest("%")
}
if (i==2)
{
//title ascending
Toast.makeText(this,"Title(Ascending)",Toast.LENGTH_SHORT).show()
val editor = mSharedPref!!.edit()
editor.putString("Sort", "ascending")
editor.apply()
LoadQueryAscending("%")
}
if (i==3)
{
//title descending
Toast.makeText(this,"Title(Descending)",Toast.LENGTH_SHORT).show()
val editor = mSharedPref!!.edit()
editor.putString("Sort", "Descending")
editor.apply()
LoadQueryDescending("%")
}
dialogInterface.dismiss()
}
val mDialog = mBuilder.create()
mDialog.show()
}
inner class MyNotesAdapter : BaseAdapter {
var listNotesAdapter = ArrayList<Note>()
var context: Context? = null
constructor(context: Context, listNotesAdapter: ArrayList<Note>) : super() {
this.listNotesAdapter = listNotesAdapter
this.context = context
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
//inflate layout row.xml
var myView = layoutInflater.inflate(R.layout.row, null)
val myNote = listNotesAdapter[position]
myView.titleTv.text = myNote.noteName
myView.descTv.text = myNote.noteDes
//delete btn click
myView.deleteBtn.setOnClickListener {
var dbManager = DbManager(this.context!!)
val selectionArgs = arrayOf(myNote.noteID.toString())
dbManager.delete("ID=?", selectionArgs)
LoadQueryAscending("%")
}
//edit//update button click
myView.editBtn.setOnClickListener {
GoToUpdateFun(myNote)
}
//copy btn click
myView.copyBtn.setOnClickListener {
//get title
val title = myView.titleTv.text.toString()
//get description
val desc = myView.descTv.text.toString()
//concatinate
val s = title + "\n" + desc
val cb = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
cb.text = s // add to clipboard
Toast.makeText(this@MainActivity, "Copied...", Toast.LENGTH_SHORT).show()
}
//share btn click
myView.shareBtn.setOnClickListener {
//get title
val title = myView.titleTv.text.toString()
//get description
val desc = myView.descTv.text.toString()
//concatinate
val s = title + "\n" + desc
//share intent
val shareIntent = Intent()
shareIntent.action = Intent.ACTION_SEND
shareIntent.type = "text/plain"
shareIntent.putExtra(Intent.EXTRA_TEXT, s)
startActivity(Intent.createChooser(shareIntent, s))
}
return myView
}
override fun getItem(position: Int): Any {
return listNotesAdapter[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getCount(): Int {
return listNotesAdapter.size
}
}
private fun GoToUpdateFun(myNote: Note) {
val intent = Intent(this, AddNoteActivity::class.java)
intent.putExtra("ID", myNote.noteID)
intent.putExtra("name", myNote.noteName)
intent.putExtra("des", myNote.noteDes)
startActivity(intent)
}
}
Run
Copy the code or download it in the link below, build and run.
Reference
Here are the reference links:
Number | Link |
---|---|
1. | Download Example |
2. | Follow code author |
3. | Code: Apache 2.0 License |