Skip to content

Commit

Permalink
Add bindingcollectionadapter-ktx module for kotlin
Browse files Browse the repository at this point in the history
  • Loading branch information
evant committed Sep 8, 2018
1 parent 09c3468 commit b08e83d
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class name that doesn't rely on databinding.
- Added a `app:diffConfig` binding for `RecyclerView`. If set, changes to the list will
automatically be diffed using `DiffObservableList`. This works nicely with `LiveData<List<Item>>`.
- Added `@Nullable/@NonNull` annotations for better kotlin interop.
- Added `bindingcollectionadapter-ktx` with a few extensions to make item bindings a bit nicer.

### 3.0.0-beta3
- Compile with AGP `3.2.0-rc02` for better compatibility.
Expand Down
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ android {
}

dependencies {
implementation project(':bindingcollectionadapter')
implementation project(':bindingcollectionadapter-ktx')
implementation project(':bindingcollectionadapter-recyclerview')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import androidx.recyclerview.widget.DiffUtil
import me.tatarka.bindingcollectionadapter2.ItemBinding
import me.tatarka.bindingcollectionadapter2.itembindings.OnItemBindClass
import me.tatarka.bindingcollectionadapter2.map
import me.tatarka.bindingcollectionadapter2.toItemBinding
import java.util.*

class ImmutableViewModel : ViewModel(), ImmutableListeners {

private val mutList = MutableLiveData<List<ImmutableItem>>()
private val mutList = MutableLiveData<List<ImmutableItem>>().apply {
value = (0 until 3).map { i -> ImmutableItem(index = i, checked = false) }
}
private val headerFooterList =
Transformations.map<List<ImmutableItem>, List<Any>>(mutList) { input ->
val list = ArrayList<Any>(input.size + 2)
Expand All @@ -22,11 +25,10 @@ class ImmutableViewModel : ViewModel(), ImmutableListeners {
}
val list: LiveData<List<Any>> = headerFooterList

val multipleItems = ItemBinding.of(
OnItemBindClass<Any>()
.map(String::class.java, BR.item, R.layout.item_header_footer)
.map(ImmutableItem::class.java, BR.item, R.layout.item_immutable)
).bindExtra(BR.listeners, this)
val multipleItems = OnItemBindClass<Any>().apply {
map<String>(BR.item, R.layout.item_header_footer)
map<ImmutableItem>(BR.item, R.layout.item_immutable)
}.toItemBinding().bindExtra(BR.listeners, this)

val diff: DiffUtil.ItemCallback<Any> = object : DiffUtil.ItemCallback<Any>() {
override fun areItemsTheSame(oldItem: Any, newItem: Any): Boolean {
Expand All @@ -40,14 +42,6 @@ class ImmutableViewModel : ViewModel(), ImmutableListeners {
}
}

init {
val items = ArrayList<ImmutableItem>(3)
for (i in 0..2) {
items.add(ImmutableItem(index = i, checked = false))
}
mutList.value = items
}

override fun onToggleChecked(index: Int): Boolean {
mutList.value = mutList.value!!.replaceAt(index) { item ->
item.copy(checked = !item.checked)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ class MutableViewModel : ViewModel(), Listeners {
/**
* Binds a homogeneous list of items to a layout.
*/
val singleItem = ItemBinding.of<MutableItem>(BR.item, R.layout.item)
val singleItem = itemBindingOf<MutableItem>(BR.item, R.layout.item)

val pageItem = ItemBinding.of<MutableItem>(BR.item, R.layout.item_page)
val pageItem = itemBindingOf<MutableItem>(BR.item, R.layout.item_page)

/**
* Binds multiple items types to different layouts based on class. This could have also be
Expand All @@ -52,11 +52,12 @@ class MutableViewModel : ViewModel(), Listeners {
* };
`</pre> *
*/
val multipleItems = OnItemBindClass<Any>()
.map(String::class.java, BR.item, R.layout.item_header_footer)
.map(MutableItem::class.java, BR.item, R.layout.item)
val multipleItems = OnItemBindClass<Any>().apply {
map<String>(BR.item, R.layout.item_header_footer)
map<MutableItem>(BR.item, R.layout.item)
}

val multipleItems2 = OnItemBind<Any> { itemBinding, _, item ->
val multipleItems2 = itemBindingOf<Any> { itemBinding, _, item ->
when (item::class) {
String::class -> itemBinding.set(BR.item, R.layout.item_header_footer)
MutableItem::class -> itemBinding.set(BR.item, R.layout.item)
Expand Down
1 change: 1 addition & 0 deletions bindingcollectionadapter-ktx/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
42 changes: 42 additions & 0 deletions bindingcollectionadapter-ktx/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'
apply plugin: 'signing'
apply plugin: 'kotlin-android'

android {
compileSdkVersion 28

defaultConfig {
minSdkVersion 14
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
sourceSets {
androidTest {
res {
srcDirs = ['src/androidTest/res']
}
}
}
dataBinding {
enabled = true
}
}

dependencies {
api project(':bindingcollectionadapter')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

apply from: '../publish.gradle'

20 changes: 20 additions & 0 deletions bindingcollectionadapter-ktx/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /opt/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# accessed with reflection
-keepclassmembers androidx.databinding.ViewDataBinding { private mLifecycleOwner; }
3 changes: 3 additions & 0 deletions bindingcollectionadapter-ktx/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<manifest package="me.tatarka.bindingcollectionadapter2.ktx">
<application />
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@file:Suppress("NOTHING_TO_INLINE")

package me.tatarka.bindingcollectionadapter2

import androidx.annotation.LayoutRes

/**
* Creates an `ItemBinding` with the given id and layout.
*
* @see ItemBinding.of
*/
inline fun <T> itemBindingOf(variableId: Int, @LayoutRes layoutRes: Int): ItemBinding<T> =
ItemBinding.of(variableId, layoutRes)

/**
* Creates an `ItemBinding` with the given callback.
*
* @see ItemBinding.of
*/
inline fun <T> itemBindingOf(
noinline onItemBind: (
@ParameterName("itemBinding") ItemBinding<in T>,
@ParameterName("position") Int,
@ParameterName("item") T
) -> Unit
): ItemBinding<T> = ItemBinding.of(onItemBind)

/**
* Converts an `OnItemBind` to a `ItemBinding`.
*
* @see ItemBinding.of
*/
inline fun <T> OnItemBind<T>.toItemBinding(): ItemBinding<T> =
ItemBinding.of(this)

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@file:Suppress("NOTHING_TO_INLINE")

package me.tatarka.bindingcollectionadapter2

import androidx.annotation.LayoutRes
import me.tatarka.bindingcollectionadapter2.itembindings.OnItemBindClass

/**
* Maps the given type to the given id and layout.
*
* @see OnItemBindClass.map
*/
inline fun <reified T> OnItemBindClass<in T>.map(variableId: Int, @LayoutRes layoutRes: Int) {
map(T::class.java, variableId, layoutRes)
}

/**
* Maps the given type to the given callback.
*
* @see OnItemBindClass.map
*/
inline fun <reified T> OnItemBindClass<in T>.map(
noinline onItemBind: (
@ParameterName("itemBinding") ItemBinding<in T>,
@ParameterName("position") Int,
@ParameterName("item") T
) -> Unit
) {
map(T::class.java) { itemBinding, position, item ->
onItemBind(
itemBinding as ItemBinding<in T>,
position,
item
)
}
}
5 changes: 4 additions & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
include ':app', ':bindingcollectionadapter', ':bindingcollectionadapter-recyclerview'
include ':app',
':bindingcollectionadapter',
':bindingcollectionadapter-ktx',
':bindingcollectionadapter-recyclerview'

0 comments on commit b08e83d

Please sign in to comment.