Ogya — A kotlin ‘mini library’ for Dialogs and Recycler Views

Ogya

Usage

android { 

dataBinding { enabled = true }
}
  • Add it in your root build.gradle at the end of repositories:
allprojects { 
repositories {
… maven {
url ‘https://jitpack.io'
}
}
  • Add the dependency
dependencies 
{
implementation ‘com.github.billkainkoom:ogya:0.50’
}

Quick List (Listable Adapter)

Quick list simply gives you one method to use for all types of list

Idealistic way to use Quick List

object ListableTypes {
val Person = ListableType(R.layout.person)
val Animal = ListableType(R.layout.animal)
val Furniture = ListableType(R.layout.furniture)
}

Please note that all layouts used should be data-binding compatible, that is it must be of this form

<?xml version="1.0" encoding="utf-8"?>
<layout>
...
</layout>

Now let your classes that you wish to display in a list implement Listable eg

data class MyPerson(val name: String = "", val email: String = "", val type: ListableType = ListableTypes.Person) : Listable {
override fun getListableType(): ListableType? {
return type
}
}
data class Animal(val name: String = "", val specie: String = "") : Listable {
override fun getListableType(): ListableType? {
return ListableTypes.Animal
}
}
data class Furniture(val name: String = "", val specie: String = "") : Listable {
override fun getListableType(): ListableType? {
return ListableType(R.layout.furniture)
}
}

Well thats it you are almost there…

Assuming this was your data source

val peopleAndThings  = mutableListOf(
MyPerson(name = "Kwasi Malopo", email = "kwasimalopo@outlook.com"),
MyPerson(name = "Adwoa Lee", email = "adwoalee@gmail.com", type = ListableTypes.Furniture),
Animal(name = "Cassava", specie = "Plantae"),
Animal(name = "Cat", specie = "Felidae"),
Furniture(name = "Cat", specie = "Felidae")
)

Go ahead and show your list by calling loadList from ListableHelper

ListableHelper.loadList(
context = context,
recyclerView = recyclerView,
listableType = ListableTypes.Person,
listables = peopleAndThings,
listableBindingListener = { listable, listableBinding, position ->
when (listable) {
is MyPerson -> {
if (listableBinding is PersonBinding) {
listableBinding.name.text = listable.name
listableBinding.email.text = listable.email
} else if (listableBinding is FurnitureBinding) {
listableBinding.image.setImageResource(R.drawable.ic_info_outline_black_24dp)
listableBinding.name.text = listable.name
listableBinding.specie.text = listable.email
}
}
is Animal -> {
if (listableBinding is AnimalBinding) {
listableBinding.name.text = listable.name
listableBinding.specie.text = listable.specie
}
}
is Furniture -> {
if (listableBinding is FurnitureBinding) {
listableBinding.image.setImageResource(R.drawable.ic_info_outline_black_24dp)
listableBinding.name.text = listable.name
listableBinding.specie.text = listable.specie
}
}
}
},
listableClickedListener = { listable, listableBinding, position ->
when (listable) {
is MyPerson -> {
Toast.makeText(context, listable.name, Toast.LENGTH_SHORT).show()
}
}
},
layoutManagerType = LayoutManager.Vertical
)

PersonBinding is the DataBinding Class that was generated by Android’s Databinding Library for the layout R.layout.person

Listable

interface Listable {
fun getListableType(): ListableType?
}

ListableType

class ListableType(val layout: Int = 0)

Listable Helper

fun <T : Listable> loadList(context: Context, 
recyclerView: RecyclerView,
listables: MutableList<T>,
listableType: ListableType,
listableBindingListener: (T, ViewDataBinding, Int) -> Unit = { x, y, z -> },
listableClickedListener: (T, ViewDataBinding,Int) -> Unit = { x, y,z -> },
layoutManagerType: LayoutManager = LayoutManager.Vertical,
stackFromEnd: Boolean = false
): ListableAdapter<T>

Quick Dialog

Quick dialog simply gives you multiple consistent variants of dialogs you need in your Android App.

  • Message Dialog
  • Progress Dialog
  • Alert Dialog
  • Input Dialog

Message Dialog

QuickDialog(
context = this,
style = QuickDialogType.Message,
title = "Hello World",
message = "The quick dialog jumped over the old dialog",
image = R.drawable.ic_info_outline_black_24dp)
.overrideButtonNames("OK" ).overrideClicks({ ->
Toast.makeText(context, "Clicked on OK", Toast.LENGTH_SHORT).show()
}).show()

Progress Dialog

QuickDialog(
context = context,
style = QuickDialogType.Progress,
title = "Please wait",
message = "Walking round the world")
.show()

This variant however shows a button so that a user can dismiss the dialog

QuickDialog(
context = context,
style = QuickDialogType.Progress,
title = "Please wait",
message = "Walking round the world")
.overrideButtonNames("Hide Progress")
.overrideClicks({ ->
Toast.makeText(context, "Clicked on Hide Progress", Toast.LENGTH_SHORT).show()
}).showPositiveButton()
.show()

Alert Dialog

QuickDialog(
context = context,
style = QuickDialogType.Alert,
title = "Proceed",
message = "Do you want to take this action")
.overrideButtonNames("Yes", "No")
.overrideClicks(positiveClick = { ->
Toast.makeText(context, "Yes", Toast.LENGTH_SHORT).show()
}, negativeClick = { ->
Toast.makeText(context, "No", Toast.LENGTH_SHORT).show()
})
.show()

The overrideClicks appears in three forms

OverrideClicks #1

fun overrideClicks(
positiveClick: () -> Unit = {},
negativeClick: () -> Unit = {},
neutralClick: () -> Unit = {}
)

OverrideClicks #2

fun overrideClicks(
positiveClick: (dismiss: () -> Unit) -> Unit = { d -> },
negativeClick: (dismiss: () -> Unit) -> Unit = { d -> },
neutralClick: (dismiss: () -> Unit) -> Unit = { d -> }
)

The variable d is an anonymos function that is passed from the implemetation of the overideClicks function. It is the dismiss function in QuickDialog and it helps you dismiss the dialog in the click closure. All overloaded methods with dsupplied do not dismiss automatically.

Lets see an example

QuickDialog(
context = context,
style = QuickDialogType.Alert,
title = "Proceed",
message = "Do you want to take this action")
.overrideButtonNames("Yes", "No")
.overrideClicks(positiveClick = { dismiss ->
if (true) {
Toast.makeText(context, "Yes", Toast.LENGTH_SHORT).show()
dismiss()
}
}, negativeClick = { dismiss ->
if (true) {
Toast.makeText(context, "No", Toast.LENGTH_SHORT).show()
dismiss()
}
})
.show()

If we dont invoke dismiss the Quick dialog wont disappear.

OverrideClicks #3

fun overrideClicks(
positiveClick: (dismiss: () -> Unit, inputText: String) -> Unit = { d, s -> },
negativeClick: (dismiss: () -> Unit, inputText: String) -> Unit = { d, s -> },
neutralClick: (dismiss: () -> Unit, inputText: String) -> Unit = { d, s -> }
)

The d variable is same as the one described above. However the s is text that a user entered in the WithInput variation of the Quick dialog

lets see an example

QuickDialog(
context = context,
style = QuickDialogType.WithInput,
title = "Verify Code",
message = "Please verify the SMS code that was sent to you")
.overrideButtonNames("Verify", "Cancel", "Re-send")
.overrideClicks(positiveClick = { dismiss, inputText ->
if (inputText.length < 3) {
Toast.makeText(context, "Please enter a 4 digit code", Toast.LENGTH_SHORT).show()
} else if (inputText == "4000") {
Toast.makeText(context, "Verified", Toast.LENGTH_SHORT).show()
dismiss()
} else {
Toast.makeText(context, "You entered the wrong code", Toast.LENGTH_SHORT).show()
}
}, negativeClick = { dismiss, inputText ->
dismiss()
}, neutralClick = { dismiss, inputText ->
//Your action
dismiss()
})
.withInputHint("Code")
.withInputLength(4)
.withInputType(InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL)
.showNeutralButton()
.show()

You can find Ogya on GitHub by following this link

All suggestions and contributions are welcome

Software Engineer with great love for Mathematics especially Abstract Mathematics.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store