AndroidKit is a small kotlin toolkit for android development. It is not intended to replace other libraries like Anko and the like which already are very powerful. But most of the time you only use a small potion of libraries like these. That is why this project focuses on a very specific approach to android app development. More on this approach later. Until then just have a quick look on what androidKit has to offer.
dependencies{
compile 'com.github.hkokocin.atheris:AndroidKit:0.3'
}
repositories{
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
}
dependencies{
compile ('com.github.hkokocin.atheris:AndroidKit:0.5-SNAPSHOT') { changing = true }
}
The following works in Activities as well as in Fragments and their support library versions. Note that if you want to use e.g. the support Fragment you have to explicitely import the support library into your project.
class MainActivity : Activity(){
private val textView: TextView by viewId(R.id.tv_name)
private val recyclerView by viewId<RecyclerView>(R.id.rv_items)
}
class MainActivity : Activity() {
private val name: String by resource(R.string.name)
private val label by resource<String>(R.string.label)
}
Supported types are:
- String
- Array<String>
- CharSequence
- Array<CharSequence>
- Int
- Array<Int>
- Boolean
- Drawable
However there are some special cases that need to be retrieved differently
class MainActivity : Activity() {
private val dimension by dimensionInPixels(R.dimen.activity_horizontal_margin)
private val color by colorResource(R.color.primary)
}
This works for Activities only
class MainActivity : Activity() {
private val id: String? by extra("ID")
private val id2: String by extra("ID", "defaultId")
private val id3 by extra<String>("ID", "defaultId")
}
Supported are all possible extra types except Parcelables. They are currently not supported since I think you should avoid the overhead that comes with using them. Instead I prefer to pass ids and fetch the complete data from the data layer.
This can again be used in Activites as well as Fragments
start<CategoryDetailActivity>()
startForResult<CategoryDetailActivity>(REQUEST_CODE)
start<CategoryDetailActivity> {
// you can initialize the intent here
putExtra("ID", "12345")
}
context.alertDialog {
message("message")
positiveButton("Yes") { doSomething() }
negativeButton("No")
}
context.windowManager
context.inputMethodManager
Create snackbars from any view.
view.snackbar("message")
view.snackbar("message", Snackbar.LENGTH_SHORT)
view.snackbar("message"){
setAction("dismiss"){ dismiss() }
}
view.onClick{ doSomething() }
view.onLongClick{ doSomething() }
view.onTouch{view, motionEvent -> doSomething() }
view.onAttachedToWindow{ doSomething() }
view.onDetachedToWindow{ doSomething() }
view.onLayoutChanged{ doSomething() }
// ---
editText.textChange{ doSomething(editText.text) }
editText.beforeTextChange{ doSomething(editText.text) }
editText.afterTextChange{ doSomething(editText.text) }
// ---
spinner.itemSelected{ item -> doSomething(item) }
This library consists almost exclusively of extension functions which are pretty hard to test since you can not mock them. That is why I introduced the AndroidKit
class. Each extension function delegates to a function on AndroidKit
adding the extension functions context (Context
, View
, Activity
, etc) as a parameter.
AndroidKit
is a singleton and you can replace its instance in your tests:
val kit: AndroidKit = mock()
@Before
fun setUp(){
AndroidKit.instance = kit
}
Normally it should not be necessary but you can also reset this instance to the default implementation:
AndroidKit.resetToDefault()
This is not an ideal solution but it works fine. if you know a better approach please let me know.