Libraries written in Kotlin and used in most EL Passion Android projects.
1. Overview
In EL Passion we believe that every library should be as small as possible, and do one thing, but do it well.
That’s why we follow highly modularized approach.
1.1. Building with JitPack
repositories {
maven { url "https://jitpack.io" }
}
2. Espresso
Espresso module contains useful stuff when writing tests using espresso framework.
For example instead of writing
Espresso.onView(ViewMatchers.withId(R.id.button))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
Leveraging the kotlin expressiveness we can write:
onId(existingId).isDisplayed()
2.1. Download:
androidTestImplementation "com.github.elpassion.android-commons:espresso:0.0.23"
Back to Overview
3. RxJava2-test
RxJava2-test module basically contains two things.
-
Set of extension methods useful when stubbing api
For example instead of writing:
whenever(api.makeRequest()).thenReturn(Completable.error(RuntimeException()))
We can write:
whenever(api.invoke()).thenError(error)
There are corresponding methods for Observable, and Single classes as well.
-
Set of assertions for testObservers
-
assertValueThat
Observable.just(4, -1).test().assertValueThat { it > 0 }
-
assertValuesThat
Observable.just(2, 3, 4).test().assertValuesThat { it > 0 }
-
assertLastValueThat
Observable.just(1, 2).test().assertLastValue(2)
-
3.1. Download:
androidTestImplementation "com.github.elpassion.android-commons:rxjava-test:0.0.23"
Back to Overview
4. SharedPreferences
This is a core module which provides an abstraction over android shared preferences.
interface SharedPreferenceRepository<T> {
fun write(key: String, value: T?)
fun read(key: String): T?
fun contains(key: String): Boolean
}
To create an instance of it use the factory method:
val repository = createSharedPrefs<String>(sharedPreferences, jsonAdapter)
A JsonAdapter is a class which fulfills following contract:
interface JsonConverterAdapter<T> {
fun toJson(t: T?): String
fun fromJson(t: String): T?
}
As you see any class that can serialize objects to strings and later deserialize them will do.
We have created two adapters for the most commonly used serialization libraries:
There is also an extension method which binds any field into specific key from shared preferences
var secretKey by repository.asProperty("secret-key")
or you can use its non-nullable variant
var secretKeyWithDefault by repository.asPropertyWithDefault("secret-key", "12345678")
If you are reading very often we suggest you to wrap your sharedPreferences instance with CachingSharedPreferences wrapper. It uses the same interface so it is transparent from the usage perspective. Keep in mind that in order to cache values and properly invalidate them, every interactions with sharedPreferences must now go through the same instance of the caching wrapper.
4.1. Download:
implementation "com.github.elpassion.android-commons:shared-preferences:0.0.23"
Back to Overview
5. SharedPreferences-Moshi
It is a moshi adapter for our sharedPreferences library.
To create an instance of it use a factory function:
val jsonAdapter = moshiConverterAdapter<String>()
5.1. Download:
implementation "com.github.elpassion.android-commons:shared-preferences-moshi-converter-adapter:0.0.23"
Back to Overview
6. SharedPreferences-Gson
It is a gson adapter for our sharedPreferences library.
To create an instance of it use a factory function:
val jsonAdapter = gsonConverterAdapter<String>()
6.1. Download:
implementation "com.github.elpassion.android-commons:shared-preferences-gson-converter-adapter:0.0.23"
Back to Overview
7. View
This module contains useful extensions defined for both View
and ViewGroup
classes.
-
View
-
show - sets the visibility property of view to
VISIBLE
view.show()
-
hide - sets the visibility property of view to
GONE
view.hide()
-
isVisible - property of type boolean. If it is true the view’s visibility is
VISIBLE
otherwise isGONE
view.isVisible = true
-
enable - sets the enable property of view to
true
view.enable()
-
disable - sets the enable property of view to
false
view.disable()
-
-
ViewGroup
-
TBD
-
8. Pager
TBD
9. Recycler
Using recycler-view have never been easier.
If all of your views are going to be the same type you can just write
val examples = listOf(
ExampleItem(name = BasicListActivity.DESCRIPTION,
onClick = { BasicListActivity.start(this) }),
ExampleItem(name = BasicRecyclerWithSectionActivity.DESCRIPTION,
onClick = { BasicRecyclerWithSectionActivity.start(this) }),
ExampleItem(name = BasicMutableRecyclerWithSectionsActivity.DESCRIPTION,
onClick = { BasicMutableRecyclerWithSectionsActivity.start(this) }),
ExampleItem(name = BasicContactsListActivity.DESCRIPTION,
onClick = { BasicContactsListActivity.start(this) })
)
recyclerView.adapter = basicAdapterWithLayoutAndBinder(examples, R.layout.example_item) { holder, item ->
holder.itemView.example_name.text = item.name
holder.itemView.setOnClickListener { item.onClick() }
}
If you want to get benefits of using stableIds all you need to do is to make your item
implement WithStableId
interface and of course tell the adapter to use stable ids:
adapter.setHasStableId(true)
On the other hand if you need to have different views for different types of items you just need to write
val users = createManyUsers()
recyclerView.adapter = basicAdapterWithConstructors(users) { position ->
getLayoutAndConstructor(users[position])
}
}
private fun getLayoutAndConstructor(user: User) = when (user.organization) {
"A" -> R.layout.github_item to ::SimpleUserViewHolder
else -> R.layout.other_github_item to ::OtherSimpleUserViewHolder
}
Where a view holder may look like this
class SimpleUserViewHolder(itemView: View) : ViewHolderBinder<User>(itemView) {
override fun bind(item: User) {
itemView.userName.text = item.name
itemView.organization.text = item.organization
}
}
Dividing your data set into logical pieces is supported by ListWithSections
class.
Here is an example:
val users = createManyUsers()
.groupByTo(LinkedHashMap(), User::organization)
.mapValuesTo(LinkedHashMap()) { it.value }
.asBasicListWithMutableSections()
val adapter = basicAdapterWithConstructors(users) { position ->
when (users[position].organization) {
"A" -> R.layout.github_item to ::SimpleUserViewHolder
else -> R.layout.other_github_item to ::OtherSimpleUserViewHolder
}
}
There is also a mutable equivalent of this class ListWithMutableSections
.
With use of it you can e.g. clear all section at once
users.sections["Organization 1"]!!.clear()
adapter.notifyDataSetChanged()
9.1. Download:
implementation "com.github.elpassion.android-commons:recycler:0.0.23"
Back to Overview