Ogya
Ogya is a set of tools for quick android development. It gives you a consistent way to display dialogs and load lists with only one recycler adapter. The adapter can handle multiple view types. Do more with less.
- Quick Dialog for dialogs
- Quick Lists for recycler views
- Quick Permissions for permissions
Usage
-
Enabled android data binding
-
Add it in your root build.gradle at the end of repositories:
-
Add the dependency
Quick List (Listable Adapter)
Quick list simply gives you one method to use for all types of list
Idealistic way to use Quick List
First create an Object eg(ListableTypes) in Kotlin like
Please note that all layouts used should be data-binding compatible, that is it must be of this form
Now let your classes that you wish to display in a list implement Listable
eg
Well thats it you are almost there...
Assuming this was your data source
Go ahead and show your list by calling loadList from ListableHelper
PersonBinding is the DataBinding Class that was generated by Android's Databinding Library for the layout R.layout.person
Listable
Listable is an abstract class that all classes that you wish to display in a list should implement.
The identifier
is used by the diffUtils to find out which objects are the same and those that have changed in the case of an update (When you submit a new List using listableAdapter.submitList(list)
).
The span
is used when you want to have dynamic span lengths when using LayoutManager.Grid
to display your list. This helps you to create a list with items having different spans on different rows.
@Transient
: Marks the JVM backing field of the annotated property as transient, meaning that it is not part of the default serialized form of the object.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-transient/index.html
ListableType
The listable type is a simple class that tells listable adapter what type of layout to use.
Its defined as
Listable Helper
The listableHelper is a set of functions and variables that make the usage of QuickList easier.
The constructor is internal to the module so it cannot be instantiated from your code.
To display items in a list just call the public function loadList(...) in ListableHelper
Arguments in LoadList
Variable | Purpose |
---|---|
context | context |
recyclerView | is a reference to your recycler view |
listables | is a reference to your recycler viewis a mutable list of objects that you want to render in a list. All objects in this list should implement the Listable interface. |
listableType | Default type to use when no listableType is not specified on an object |
listableBindingListener | An anonymous function that supplies you with a listable its position and a viewDataBinder to display information |
listableClickedListener | An anonymous function that supplies you with a listable its position and a viewDataBinder. It is called when an item on the list is clicked |
layoutManagerType | Type of layout manager that ListableAdapter would set to the recyclerView supplied |
stackFromEnd | A boolean which determines whether a recycler view should be stacked from end or not |
loadList returns a ListableAdapter
Methods on ListableAdapter
Method | Purpose |
---|---|
submitList(list: MutableList<T>) |
Submits list to ListableAdapter -> Which would use diffutils to calculate changes and render results. This method is called in ListableHelper.loadList, so only use it when you want to update your list. It supersedes all other change (eg . Add , Remove , Replace etc ...) calls. |
removeAt(position: Int) |
Removes listable at a position |
addAt(position: Int, listable: T) |
Add a listable at position |
replaceAt(position: Int, listable: T) |
Replace listable at position |
addAt(position: Int, vararg listable: T) |
Add listable(s) at position eg listableAdapter |
addAt(position: Int, newListables: List) |
Add listable(s) at position |
add(newListables: List) |
Add listable(s). This would add to bottom of the list |
add(listable: T) |
Add listable. This would add to bottom of the list |
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
A message dialog simply displays an image with one button.
Progress Dialog
A progress dialog shows a circular progress in an indeterminate state with or without a button
This variant however shows a button so that a user can dismiss the dialog
Alert Dialog
An alert dialog is used in situations when a user has to make a decision
The overrideClicks appears in three forms
OverrideClicks #1
OverrideClicks #2
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 d supplied do not dismiss automatically.
Lets see an example
If we dont invoke dismiss the Quick dialog wont disappear.
OverrideClicks #3
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
Quick Permissions
In pre-lollipop permission checking was not really an issue. Just add it to your manifest
and you are good to go. However in the post lollipop era we have to deal with runtime permissions. Quick Permissions makes it easier for you to request permissions at runtime.
Componentization
In previous versions of Ogya, the listableBindingListener looked something like this
This is quite ok. But Imagine you had a project where you had to display persons at multiple places. You would need to set the properties over and over again in all places. But with Componentization. Its done at one place and the change ripples across your entire project.
Componentization Axioms
- A component should have its dependencies injected into it
- A components state is determined by the listable object that’s passed to it.
Origins
All components are derived from the abstract class BaseComponent.
It’s a generic abstract class that expects a ViewDataBinding Type and a Listable (any class that extends Listable) Type. The ViewDataBinding files are generated classes created by any layout file which has a root parent of <layout>
.
Function: Render
The render method is used to display the component.
Function: ListableType
The listableType function returns the listableType of the component.
Lets Dive In
The Kotlin language provides as with beautiful structures. One such structure is object.
An object is a thread-safe singleton class. Our derived components are all objects. They have no constructors and they do not keep state. The only state they know of is the state of the listable.
Then …
This makes it easy to reuse code. As long as dependencies are provided for render, the components can be recreated with its expected behavior.
Ogya Forms
There are hardly any android apps built without forms. It can be daunting especially when you have forms all over the place.
Usually they lead to never ending xml files or really long xml files. And then there is the case where the form contains other elements
which are not inputs eg info cards, images etc. Most at times we will just repeat the form code in all xmls that they are needed in
or probably use the include tag (but there is no for-loop for
component reuse by Componentization in Ogya. All we needed to do was to
1. Add a component that can accept input.
I see the confusion in type and inputType. So lets break that down.
type
This just toggles between date,time and input. Basically they are all inputs but time gives you the
opportunity to select from the android TimePicker, date also does the same but gives you a DatePicker instead.
Both type time and date gives you an un-editable input. Type input allows you to use the keyboard as the input source.
2. Decide the keyboard type based on the input.
As you can see the inputType parameter expects the android textInput type. Pass any of these and you will get its respective
keyboard.
3. Add a watcher to track value changes of input element.
This means you can pass any layout you prefer. Just make sure of the following.
-
The layout has an EditText with tag "input". If absent the watcher wont recognize any changes since its only watching
for changes on an EditText with tag input. -
Your component's signature is
ListableAdapter has been extended with one more function : retrieveFormValues
And you use it like this:
And that's it!