From 3f144bdbeeda6057d244b6a6eabff7b1f73d32ba Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sat, 14 Sep 2019 13:05:03 -0700 Subject: Add initial binding --- .../fastadapter/databinding/BindingItem.kt | 122 +++++++++++++++++++++ .../fastadapter/databinding/FastBindingAdapter.kt | 45 ++++++++ 2 files changed, 167 insertions(+) create mode 100644 fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/BindingItem.kt create mode 100644 fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/FastBindingAdapter.kt (limited to 'fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding') diff --git a/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/BindingItem.kt b/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/BindingItem.kt new file mode 100644 index 0000000..e52838b --- /dev/null +++ b/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/BindingItem.kt @@ -0,0 +1,122 @@ +package ca.allanwang.fastadapter.databinding + + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.databinding.DataBindingUtil +import androidx.databinding.ViewDataBinding +import androidx.recyclerview.widget.RecyclerView +import ca.allanwang.gitdroid.logger.L +import ca.allanwang.gitdroid.views.BR +import com.bumptech.glide.Glide +import com.mikepenz.fastadapter.FastAdapter +import com.mikepenz.fastadapter.items.AbstractItem +import com.mikepenz.fastadapter.listeners.ClickEventHook + +typealias GenericBindingItem = BindingItem<*> + +abstract class BindingItem(open val data: Any?) : AbstractItem(), + BindingLayout { + + override val type: Int + get() = layoutRes + + override fun createView(ctx: Context, parent: ViewGroup?): View { + val binding: ViewDataBinding = DataBindingUtil.inflate( + LayoutInflater.from(ctx), + layoutRes, parent, + false, + null + ) + return binding.root + } + + final override fun bindView(holder: ViewHolder, payloads: MutableList) { + super.bindView(holder, payloads) + val binding = DataBindingUtil.getBinding(holder.itemView) ?: return + binding.bindView(holder, payloads) + binding.executePendingBindings() + } + + open fun Binding.bindView(holder: ViewHolder, payloads: MutableList) { + setVariable(BR.model, data) + } + + final override fun unbindView(holder: ViewHolder) { + super.unbindView(holder) + val binding = DataBindingUtil.getBinding(holder.itemView) ?: return + binding.unbindView(holder) + binding.unbind() + } + + open fun Binding.unbindView(holder: ViewHolder) {} + + final override fun getViewHolder(v: View): ViewHolder = ViewHolder(v, layoutRes) + + override fun failedToRecycle(holder: ViewHolder): Boolean { + L.e { "Failed to recycle" } + return super.failedToRecycle(holder) + } + + companion object { + @JvmStatic + protected fun unbindGlide(vararg imageView: ImageView) { + if (imageView.isEmpty()) { + return + } + val manager = Glide.with(imageView.first().context) + imageView.forEach { manager.clear(it) } + } + + @JvmStatic + protected fun unbind(vararg imageView: ImageView) { + imageView.forEach { it.setImageDrawable(null) } + } + + @JvmStatic + protected fun unbind(vararg textView: TextView) { + textView.forEach { it.text = null } + } + } + + class ViewHolder(itemView: View, internal val layoutRes: Int) : RecyclerView.ViewHolder(itemView) + +} + +interface BindingLayout { + val layoutRes: Int +} + + +abstract class BindingClickEventHook>(val identifier: BindingLayout) : + ClickEventHook() { + + private fun RecyclerView.ViewHolder.binding(): Binding? { + val holder = this as? BindingItem.ViewHolder ?: return null + if (holder.layoutRes != identifier.layoutRes) { + return null + } + return DataBindingUtil.getBinding(itemView) + } + + final override fun onBind(viewHolder: RecyclerView.ViewHolder): View? = + viewHolder.binding()?.onBind(viewHolder) ?: super.onBind(viewHolder) + + open fun Binding.onBind(viewHolder: RecyclerView.ViewHolder): View? = super.onBind(viewHolder) + + final override fun onBindMany(viewHolder: RecyclerView.ViewHolder): List? = + viewHolder.binding()?.onBindMany(viewHolder) ?: super.onBindMany(viewHolder) + + open fun Binding.onBindMany(viewHolder: RecyclerView.ViewHolder): List? = super.onBindMany(viewHolder) + + final override fun onClick(v: View, position: Int, fastAdapter: FastAdapter, item: Item) { + val binding: Binding = DataBindingUtil.findBinding(v) ?: return + binding.onClick(v, position, fastAdapter, item) + } + + abstract fun Binding.onClick(v: View, position: Int, fastAdapter: FastAdapter, item: Item) +} \ No newline at end of file diff --git a/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/FastBindingAdapter.kt b/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/FastBindingAdapter.kt new file mode 100644 index 0000000..2270b5d --- /dev/null +++ b/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/FastBindingAdapter.kt @@ -0,0 +1,45 @@ +package ca.allanwang.fastadapter.databinding + +import com.mikepenz.fastadapter.FastAdapter +import com.mikepenz.fastadapter.IAdapter +import com.mikepenz.fastadapter.IItemAdapter +import com.mikepenz.fastadapter.adapters.ItemAdapter +import com.mikepenz.fastadapter.diff.FastAdapterDiffUtil + +class FastBindingAdapter private constructor(private val adapter: ItemAdapter) : + FastAdapter(), + IItemAdapter by adapter { + + constructor() : this(ItemAdapter()) + + var lastClearTime: Long = -1 + + init { + super.addAdapter(0, adapter) + } + + override fun clear(): FastBindingAdapter { + if (itemCount != 0) { + adapter.clear() + lastClearTime = System.currentTimeMillis() + } + return this + } + + override fun > addAdapter( + index: Int, + adapter: A + ): FastAdapter { + throw IllegalArgumentException("FastBindingAdapter only allows one adapter") + } + + fun setWithDiff(items: List, detectMoves: Boolean = true) { + FastAdapterDiffUtil.set( + adapter, + items, + null, + detectMoves + ) + } + +} \ No newline at end of file -- cgit v1.2.3 From fe69957ee3a38023e3e7d1d9555523c69eef2ac2 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sat, 14 Sep 2019 17:53:48 -0700 Subject: Use newer data binding and remove single fast adapter --- core-ui/src/main/res-public/values/public.xml | 6 +-- core/src/main/res-public/values/public.xml | 34 ++++++------ .../fastadapter/databinding/BindingItem.kt | 60 +++++++++------------- .../fastadapter/databinding/FastBindingAdapter.kt | 45 ---------------- 4 files changed, 43 insertions(+), 102 deletions(-) delete mode 100644 fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/FastBindingAdapter.kt (limited to 'fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding') diff --git a/core-ui/src/main/res-public/values/public.xml b/core-ui/src/main/res-public/values/public.xml index f62ed25..c8c2e56 100644 --- a/core-ui/src/main/res-public/values/public.xml +++ b/core-ui/src/main/res-public/values/public.xml @@ -1,10 +1,10 @@ + + + - - - \ No newline at end of file diff --git a/core/src/main/res-public/values/public.xml b/core/src/main/res-public/values/public.xml index 443f32e..211c539 100644 --- a/core/src/main/res-public/values/public.xml +++ b/core/src/main/res-public/values/public.xml @@ -1,25 +1,20 @@ + - + + + + + - - - - - - - - - - - - - + + + @@ -105,7 +100,6 @@ - @@ -113,6 +107,12 @@ - - + + + + + + + + \ No newline at end of file diff --git a/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/BindingItem.kt b/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/BindingItem.kt index e52838b..d800fcd 100644 --- a/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/BindingItem.kt +++ b/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/BindingItem.kt @@ -1,25 +1,24 @@ package ca.allanwang.fastadapter.databinding - import android.content.Context import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView import androidx.databinding.DataBindingUtil import androidx.databinding.ViewDataBinding import androidx.recyclerview.widget.RecyclerView -import ca.allanwang.gitdroid.logger.L -import ca.allanwang.gitdroid.views.BR -import com.bumptech.glide.Glide +import ca.allanwang.kau.logging.KL import com.mikepenz.fastadapter.FastAdapter +import com.mikepenz.fastadapter.GenericItem import com.mikepenz.fastadapter.items.AbstractItem import com.mikepenz.fastadapter.listeners.ClickEventHook -typealias GenericBindingItem = BindingItem<*> +interface VhModel { + fun vh(): GenericItem +} -abstract class BindingItem(open val data: Any?) : AbstractItem(), +abstract class BindingItem(open val data: Any?) : + AbstractItem(), BindingLayout { override val type: Int @@ -29,22 +28,22 @@ abstract class BindingItem(open val data: Any?) : Abs val binding: ViewDataBinding = DataBindingUtil.inflate( LayoutInflater.from(ctx), layoutRes, parent, - false, - null + false ) return binding.root } + fun getBinding(holder: ViewHolder): Binding? = + DataBindingUtil.getBinding(holder.itemView) + final override fun bindView(holder: ViewHolder, payloads: MutableList) { super.bindView(holder, payloads) - val binding = DataBindingUtil.getBinding(holder.itemView) ?: return + val binding = getBinding(holder) ?: return binding.bindView(holder, payloads) binding.executePendingBindings() } - open fun Binding.bindView(holder: ViewHolder, payloads: MutableList) { - setVariable(BR.model, data) - } + abstract fun Binding.bindView(holder: ViewHolder, payloads: MutableList) final override fun unbindView(holder: ViewHolder) { super.unbindView(holder) @@ -58,40 +57,26 @@ abstract class BindingItem(open val data: Any?) : Abs final override fun getViewHolder(v: View): ViewHolder = ViewHolder(v, layoutRes) override fun failedToRecycle(holder: ViewHolder): Boolean { - L.e { "Failed to recycle" } + KL.e { "Failed to recycle" } return super.failedToRecycle(holder) } - companion object { - @JvmStatic - protected fun unbindGlide(vararg imageView: ImageView) { - if (imageView.isEmpty()) { - return - } - val manager = Glide.with(imageView.first().context) - imageView.forEach { manager.clear(it) } - } - - @JvmStatic - protected fun unbind(vararg imageView: ImageView) { - imageView.forEach { it.setImageDrawable(null) } - } - - @JvmStatic - protected fun unbind(vararg textView: TextView) { - textView.forEach { it.text = null } - } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is BindingItem<*>) return false + return identifier == other.identifier && data == other.data } - class ViewHolder(itemView: View, internal val layoutRes: Int) : RecyclerView.ViewHolder(itemView) + override fun hashCode(): Int = data.hashCode() + class ViewHolder(itemView: View, internal val layoutRes: Int) : + RecyclerView.ViewHolder(itemView) } interface BindingLayout { val layoutRes: Int } - abstract class BindingClickEventHook>(val identifier: BindingLayout) : ClickEventHook() { @@ -111,7 +96,8 @@ abstract class BindingClickEventHook? = viewHolder.binding()?.onBindMany(viewHolder) ?: super.onBindMany(viewHolder) - open fun Binding.onBindMany(viewHolder: RecyclerView.ViewHolder): List? = super.onBindMany(viewHolder) + open fun Binding.onBindMany(viewHolder: RecyclerView.ViewHolder): List? = + super.onBindMany(viewHolder) final override fun onClick(v: View, position: Int, fastAdapter: FastAdapter, item: Item) { val binding: Binding = DataBindingUtil.findBinding(v) ?: return diff --git a/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/FastBindingAdapter.kt b/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/FastBindingAdapter.kt deleted file mode 100644 index 2270b5d..0000000 --- a/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/FastBindingAdapter.kt +++ /dev/null @@ -1,45 +0,0 @@ -package ca.allanwang.fastadapter.databinding - -import com.mikepenz.fastadapter.FastAdapter -import com.mikepenz.fastadapter.IAdapter -import com.mikepenz.fastadapter.IItemAdapter -import com.mikepenz.fastadapter.adapters.ItemAdapter -import com.mikepenz.fastadapter.diff.FastAdapterDiffUtil - -class FastBindingAdapter private constructor(private val adapter: ItemAdapter) : - FastAdapter(), - IItemAdapter by adapter { - - constructor() : this(ItemAdapter()) - - var lastClearTime: Long = -1 - - init { - super.addAdapter(0, adapter) - } - - override fun clear(): FastBindingAdapter { - if (itemCount != 0) { - adapter.clear() - lastClearTime = System.currentTimeMillis() - } - return this - } - - override fun > addAdapter( - index: Int, - adapter: A - ): FastAdapter { - throw IllegalArgumentException("FastBindingAdapter only allows one adapter") - } - - fun setWithDiff(items: List, detectMoves: Boolean = true) { - FastAdapterDiffUtil.set( - adapter, - items, - null, - detectMoves - ) - } - -} \ No newline at end of file -- cgit v1.2.3 From 96b0895a15d1c637075eab05a59575cce2746cfc Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sat, 14 Sep 2019 18:10:09 -0700 Subject: Add missing dependency --- about/build.gradle | 1 + .../ca/allanwang/fastadapter/databinding/BindingItem.kt | 17 ++++++++++++++++- .../ca/allanwang/kau/adapters/SingleFastAdapter.kt | 17 ++++++++++++++++- 3 files changed, 33 insertions(+), 2 deletions(-) (limited to 'fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding') diff --git a/about/build.gradle b/about/build.gradle index 274ef5c..114428b 100644 --- a/about/build.gradle +++ b/about/build.gradle @@ -11,6 +11,7 @@ android { dependencies { implementation project(':core-ui') implementation project(':fastadapter') + implementation Dependencies.fastAdapter("utils") api Dependencies.aboutLibraries } diff --git a/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/BindingItem.kt b/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/BindingItem.kt index d800fcd..b2b0f26 100644 --- a/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/BindingItem.kt +++ b/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/BindingItem.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2019 Allan Wang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package ca.allanwang.fastadapter.databinding import android.content.Context @@ -105,4 +120,4 @@ abstract class BindingClickEventHook, item: Item) -} \ No newline at end of file +} diff --git a/fastadapter/src/main/kotlin/ca/allanwang/kau/adapters/SingleFastAdapter.kt b/fastadapter/src/main/kotlin/ca/allanwang/kau/adapters/SingleFastAdapter.kt index 1155c79..e183bde 100644 --- a/fastadapter/src/main/kotlin/ca/allanwang/kau/adapters/SingleFastAdapter.kt +++ b/fastadapter/src/main/kotlin/ca/allanwang/kau/adapters/SingleFastAdapter.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2019 Allan Wang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package ca.allanwang.kau.adapters import com.mikepenz.fastadapter.FastAdapter @@ -39,4 +54,4 @@ class SingleFastAdapter private constructor(val adapter: ItemAdapter, detectMoves: Boolean = true) { FastAdapterDiffUtil.set(adapter, items, detectMoves) } -} \ No newline at end of file +} -- cgit v1.2.3