Added modules: recyclerview-adapters, kotlin-extensions
This commit is contained in:
parent
1d6d6d06be
commit
7be175f750
|
|
@ -18,7 +18,7 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
api project(":components-storable")
|
||||
api project(":storable")
|
||||
api 'net.danlew:android.joda:2.9.9.4'
|
||||
|
||||
implementation "com.android.support:support-annotations:$versions.supportLibrary"
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdkVersion versions.compileSdk
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion versions.minSdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
|
||||
implementation "com.android.support:recyclerview-v7:$versions.supportLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
<manifest
|
||||
package="ru.touchin.roboswag.components.extensions"/>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package ru.touchin.roboswag.components.extensions
|
||||
|
||||
import kotlin.properties.Delegates
|
||||
import kotlin.properties.ObservableProperty
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
/**
|
||||
* Simple observable delegate only for notification of new value.
|
||||
*/
|
||||
inline fun <T> Delegates.observable(
|
||||
initialValue: T,
|
||||
crossinline onChange: (newValue: T) -> Unit
|
||||
): ReadWriteProperty<Any?, T> = object : ObservableProperty<T>(initialValue) {
|
||||
override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) = onChange(newValue)
|
||||
}
|
||||
|
||||
inline fun <T> Delegates.distinctUntilChanged(
|
||||
initialValue: T,
|
||||
crossinline onChange: (newValue: T) -> Unit
|
||||
): ReadWriteProperty<Any?, T> = object : ObservableProperty<T>(initialValue) {
|
||||
override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) =
|
||||
if (newValue != null && oldValue != newValue) onChange(newValue) else Unit
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package ru.touchin.roboswag.components.extensions
|
||||
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
|
||||
private const val RIPPLE_EFFECT_DELAY = 150L
|
||||
|
||||
/**
|
||||
* Sets click listener to view. On click it will call something after delay.
|
||||
*
|
||||
* @param delay Delay after which click listener will be called;
|
||||
* @param listener Click listener.
|
||||
*/
|
||||
fun View.setOnRippleClickListener(delay: Long = RIPPLE_EFFECT_DELAY, listener: (View) -> Unit) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
setOnClickListener { view -> postDelayed({ if (hasWindowFocus()) listener(view) }, delay) }
|
||||
} else {
|
||||
setOnClickListener(listener)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package ru.touchin.roboswag.components.extensions
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.support.annotation.ColorInt
|
||||
import android.support.annotation.ColorRes
|
||||
import android.support.annotation.DrawableRes
|
||||
import android.support.annotation.IdRes
|
||||
import android.support.annotation.StringRes
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.view.View
|
||||
|
||||
fun <T : View> RecyclerView.ViewHolder.findViewById(@IdRes resId: Int): T = itemView.findViewById(resId)
|
||||
|
||||
val RecyclerView.ViewHolder.context: Context
|
||||
get() = itemView.context
|
||||
|
||||
fun RecyclerView.ViewHolder.getText(@StringRes resId: Int): CharSequence = context.getText(resId)
|
||||
|
||||
fun RecyclerView.ViewHolder.getString(@StringRes resId: Int): String = context.getString(resId)
|
||||
|
||||
@SuppressWarnings("SpreadOperator") // it's OK for small arrays
|
||||
fun RecyclerView.ViewHolder.getString(@StringRes resId: Int, vararg args: Any): String = context.getString(resId, *args)
|
||||
|
||||
@ColorInt
|
||||
fun RecyclerView.ViewHolder.getColor(@ColorRes resId: Int): Int = ContextCompat.getColor(context, resId)
|
||||
|
||||
fun RecyclerView.ViewHolder.getColorStateList(@ColorRes resId: Int): ColorStateList? = ContextCompat.getColorStateList(context, resId)
|
||||
|
||||
fun RecyclerView.ViewHolder.getDrawable(@DrawableRes resId: Int): Drawable? = ContextCompat.getDrawable(context, resId)
|
||||
|
|
@ -15,7 +15,7 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
api project(":components-navigation")
|
||||
api project(":navigation")
|
||||
|
||||
compileOnly "javax.inject:javax.inject:1"
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
api project(":components-utils")
|
||||
api project(":components-logging")
|
||||
api project(":utils")
|
||||
api project(":logging")
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
|
||||
|
|
|
|||
|
|
@ -5,20 +5,24 @@ if (gradle.ext.has('componentsRoot')) {
|
|||
rootDir = settingsDir
|
||||
}
|
||||
|
||||
include ':components-logging'
|
||||
include ':components-utils'
|
||||
include ':components-navigation'
|
||||
include ':components-storable'
|
||||
include ':components-api-logansquare'
|
||||
include ':components-lifecycle-common'
|
||||
include ':components-lifecycle-rx'
|
||||
include ':components-views'
|
||||
include ':logging'
|
||||
include ':utils'
|
||||
include ':navigation'
|
||||
include ':storable'
|
||||
include ':api-logansquare'
|
||||
include ':lifecycle-common'
|
||||
include ':lifecycle-rx'
|
||||
include ':views'
|
||||
include ':recyclerview-adapters'
|
||||
include ':kotlin-extensions'
|
||||
|
||||
project(':components-utils').projectDir = new File(rootDir, 'utils')
|
||||
project(':components-logging').projectDir = new File(rootDir, 'logging')
|
||||
project(':components-navigation').projectDir = new File(rootDir, 'navigation')
|
||||
project(':components-storable').projectDir = new File(rootDir, 'storable')
|
||||
project(':components-api-logansquare').projectDir = new File(rootDir, 'api-logansquare')
|
||||
project(':components-lifecycle-common').projectDir = new File(rootDir, 'lifecycle-common')
|
||||
project(':components-lifecycle-rx').projectDir = new File(rootDir, 'lifecycle-rx')
|
||||
project(':components-views').projectDir = new File(rootDir, 'views')
|
||||
project(':utils').projectDir = new File(rootDir, 'utils')
|
||||
project(':logging').projectDir = new File(rootDir, 'logging')
|
||||
project(':navigation').projectDir = new File(rootDir, 'navigation')
|
||||
project(':storable').projectDir = new File(rootDir, 'storable')
|
||||
project(':api-logansquare').projectDir = new File(rootDir, 'api-logansquare')
|
||||
project(':lifecycle-common').projectDir = new File(rootDir, 'lifecycle-common')
|
||||
project(':lifecycle-rx').projectDir = new File(rootDir, 'lifecycle-rx')
|
||||
project(':views').projectDir = new File(rootDir, 'views')
|
||||
project(':recyclerview-adapters').projectDir = new File(rootDir, 'recyclerview-adapters')
|
||||
project(':kotlin-extensions').projectDir = new File(rootDir, 'kotlin-extensions')
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
api project(":components-utils")
|
||||
api project(":components-logging")
|
||||
api project(":utils")
|
||||
api project(":logging")
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdkVersion versions.compileSdk
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion versions.minSdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api project(':kotlin-extensions')
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
|
||||
implementation "com.android.support:recyclerview-v7:$versions.supportLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
<manifest
|
||||
package="ru.touchin.roboswag.components.adapters"/>
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2017 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
|
||||
*
|
||||
* This file is part of RoboSwag library.
|
||||
*
|
||||
* 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 ru.touchin.roboswag.components.adapters;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Objects of such class controls creation and binding of specific type of RecyclerView's ViewHolders.
|
||||
* Default {@link #getItemViewType} is generating on construction of object.
|
||||
*
|
||||
* @param <TViewHolder> Type of {@link RecyclerView.ViewHolder} of delegate.
|
||||
*/
|
||||
public abstract class AdapterDelegate<TViewHolder extends RecyclerView.ViewHolder> {
|
||||
|
||||
private final int defaultItemViewType = ViewCompat.generateViewId();
|
||||
|
||||
/**
|
||||
* Unique ID of AdapterDelegate.
|
||||
*
|
||||
* @return Unique ID.
|
||||
*/
|
||||
public int getItemViewType() {
|
||||
return defaultItemViewType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if object is processable by this delegate.
|
||||
*
|
||||
* @param items Items to check;
|
||||
* @param adapterPosition Position of item in adapter;
|
||||
* @param collectionPosition Position of item in collection;
|
||||
* @return True if item is processable by this delegate.
|
||||
*/
|
||||
public abstract boolean isForViewType(@NonNull final List<Object> items, final int adapterPosition, final int collectionPosition);
|
||||
|
||||
/**
|
||||
* Returns unique ID of item to support stable ID's logic of RecyclerView's adapter.
|
||||
*
|
||||
* @param items Items in adapter;
|
||||
* @param adapterPosition Position of item in adapter;
|
||||
* @param collectionPosition Position of item in collection;
|
||||
* @return Unique item ID.
|
||||
*/
|
||||
public long getItemId(@NonNull final List<Object> items, final int adapterPosition, final int collectionPosition) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates ViewHolder to bind item to it later.
|
||||
*
|
||||
* @param parent Container of ViewHolder's view.
|
||||
* @return New ViewHolder.
|
||||
*/
|
||||
@NonNull
|
||||
public abstract TViewHolder onCreateViewHolder(@NonNull final ViewGroup parent);
|
||||
|
||||
/**
|
||||
* Binds item to created by this object ViewHolder.
|
||||
*
|
||||
* @param holder ViewHolder to bind item to;
|
||||
* @param items Items in adapter;
|
||||
* @param adapterPosition Position of item in adapter;
|
||||
* @param collectionPosition Position of item in collection that contains item;
|
||||
* @param payloads Payloads;
|
||||
*/
|
||||
public abstract void onBindViewHolder(
|
||||
@NonNull final RecyclerView.ViewHolder holder,
|
||||
@NonNull final List<Object> items,
|
||||
final int adapterPosition,
|
||||
final int collectionPosition,
|
||||
@NonNull final List<Object> payloads
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package ru.touchin.roboswag.components.adapters
|
||||
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.util.SparseArray
|
||||
import android.view.ViewGroup
|
||||
|
||||
/**
|
||||
* Manager for delegation callbacks from [RecyclerView.Adapter] to delegates.
|
||||
*/
|
||||
class DelegatesManager {
|
||||
|
||||
private val delegates = SparseArray<AdapterDelegate<*>>()
|
||||
|
||||
fun getItemViewType(items: List<*>, adapterPosition: Int, collectionPosition: Int): Int {
|
||||
for (index in 0 until delegates.size()) {
|
||||
val delegate = delegates.valueAt(index)
|
||||
if (delegate.isForViewType(items, adapterPosition, collectionPosition)) {
|
||||
return delegate.itemViewType
|
||||
}
|
||||
}
|
||||
throw IllegalStateException("Delegate not found for adapterPosition: $adapterPosition")
|
||||
}
|
||||
|
||||
fun getItemId(items: List<*>, adapterPosition: Int, collectionPosition: Int): Long {
|
||||
val delegate = getDelegate(getItemViewType(items, adapterPosition, collectionPosition))
|
||||
return delegate.getItemId(items, adapterPosition, collectionPosition)
|
||||
}
|
||||
|
||||
fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder = getDelegate(viewType).onCreateViewHolder(parent)
|
||||
|
||||
fun onBindViewHolder(holder: RecyclerView.ViewHolder, items: List<*>, adapterPosition: Int, collectionPosition: Int, payloads: List<Any>) {
|
||||
val delegate = getDelegate(getItemViewType(items, adapterPosition, collectionPosition))
|
||||
delegate.onBindViewHolder(holder, items, adapterPosition, collectionPosition, payloads)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds [PositionAdapterDelegate] to adapter.
|
||||
*
|
||||
* @param delegate Delegate to add.
|
||||
*/
|
||||
fun addDelegate(delegate: AdapterDelegate<*>) = delegates.put(delegate.itemViewType, delegate)
|
||||
|
||||
/**
|
||||
* Removes [AdapterDelegate] from adapter.
|
||||
*
|
||||
* @param delegate Delegate to remove.
|
||||
*/
|
||||
fun removeDelegate(delegate: AdapterDelegate<*>) = delegates.remove(delegate.itemViewType)
|
||||
|
||||
private fun getDelegate(viewType: Int) = delegates[viewType] ?: throw IllegalStateException("No AdapterDelegate added for view type: $viewType")
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package ru.touchin.roboswag.components.adapters
|
||||
|
||||
import android.support.v7.recyclerview.extensions.AsyncDifferConfig
|
||||
import android.support.v7.recyclerview.extensions.AsyncListDiffer
|
||||
import android.support.v7.util.DiffUtil
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.view.ViewGroup
|
||||
import ru.touchin.roboswag.components.extensions.setOnRippleClickListener
|
||||
|
||||
/**
|
||||
* Base adapter with delegation and diff computing on background thread.
|
||||
*/
|
||||
open class DelegationListAdapter<TItem>(config: AsyncDifferConfig<TItem>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
constructor(diffCallback: DiffUtil.ItemCallback<TItem>) : this(AsyncDifferConfig.Builder<TItem>(diffCallback).build())
|
||||
|
||||
var itemClickListener: ((TItem, RecyclerView.ViewHolder) -> Unit)? = null
|
||||
|
||||
private val delegatesManager = DelegatesManager()
|
||||
private var differ = AsyncListDiffer(OffsetAdapterUpdateCallback(this, ::getHeadersCount), config)
|
||||
|
||||
open fun getHeadersCount() = 0
|
||||
|
||||
open fun getFootersCount() = 0
|
||||
|
||||
override fun getItemCount() = getHeadersCount() + getList().size + getFootersCount()
|
||||
|
||||
override fun getItemViewType(position: Int) = delegatesManager.getItemViewType(getList(), position, getCollectionPosition(position))
|
||||
|
||||
override fun getItemId(position: Int) = delegatesManager.getItemId(getList(), position, getCollectionPosition(position))
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = delegatesManager.onCreateViewHolder(parent, viewType)
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, payloads: List<Any>) {
|
||||
val collectionPosition = getCollectionPosition(position)
|
||||
if (collectionPosition in 0 until getList().size) {
|
||||
if (itemClickListener != null) {
|
||||
holder.itemView.setOnRippleClickListener {
|
||||
itemClickListener?.invoke(getList()[getCollectionPosition(holder.adapterPosition)], holder)
|
||||
}
|
||||
} else {
|
||||
holder.itemView.setOnClickListener(null)
|
||||
}
|
||||
}
|
||||
delegatesManager.onBindViewHolder(holder, getList(), position, collectionPosition, payloads)
|
||||
}
|
||||
|
||||
final override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) = Unit
|
||||
|
||||
/**
|
||||
* Adds [AdapterDelegate] to adapter.
|
||||
*
|
||||
* @param delegate Delegate to add.
|
||||
*/
|
||||
fun addDelegate(delegate: AdapterDelegate<*>) = delegatesManager.addDelegate(delegate)
|
||||
|
||||
/**
|
||||
* Removes [AdapterDelegate] from adapter.
|
||||
*
|
||||
* @param delegate Delegate to remove.
|
||||
*/
|
||||
fun removeDelegate(delegate: AdapterDelegate<*>) = delegatesManager.removeDelegate(delegate)
|
||||
|
||||
/**
|
||||
* Submits a new list to be diffed, and displayed.
|
||||
*
|
||||
* If a list is already being displayed, a diff will be computed on a background thread, which
|
||||
* will dispatch Adapter.notifyItem events on the main thread.
|
||||
*
|
||||
* @param list The new list to be displayed.
|
||||
*/
|
||||
fun submitList(list: List<TItem>) = differ.submitList(list)
|
||||
|
||||
/**
|
||||
* Get the current List - any diffing to present this list has already been computed and
|
||||
* dispatched via the ListUpdateCallback.
|
||||
* <p>
|
||||
* If a <code>null</code> List, or no List has been submitted, an empty list will be returned.
|
||||
* <p>
|
||||
* The returned list may not be mutated - mutations to content must be done through
|
||||
* {@link #submitList(List)}.
|
||||
*
|
||||
* @return current List.
|
||||
*/
|
||||
fun getList(): List<TItem> = differ.currentList
|
||||
|
||||
fun getCollectionPosition(adapterPosition: Int) = adapterPosition - getHeadersCount()
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package ru.touchin.roboswag.components.adapters;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Objects of such class controls creation and binding of specific type of RecyclerView's ViewHolders.
|
||||
* Such delegates are creating and binding ViewHolders for specific items.
|
||||
* Default {@link #getItemViewType} is generating on construction of object.
|
||||
*
|
||||
* @param <TViewHolder> Type of {@link RecyclerView.ViewHolder} of delegate;
|
||||
* @param <TItem> Type of items to bind to {@link RecyclerView.ViewHolder}s.
|
||||
*/
|
||||
public abstract class ItemAdapterDelegate<TViewHolder extends RecyclerView.ViewHolder, TItem> extends AdapterDelegate<TViewHolder> {
|
||||
|
||||
@Override
|
||||
public boolean isForViewType(@NonNull final List<Object> items, final int adapterPosition, final int collectionPosition) {
|
||||
return collectionPosition >= 0
|
||||
&& collectionPosition < items.size()
|
||||
&& isForViewType(items.get(collectionPosition), adapterPosition, collectionPosition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if object is processable by this delegate.
|
||||
* This item will be casted to {@link TItem} and passes to {@link #onBindViewHolder(TViewHolder, TItem, int, int, List)}.
|
||||
*
|
||||
* @param item Item to check;
|
||||
* @param adapterPosition Position of item in adapter;
|
||||
* @param collectionPosition Position of item in collection that contains item;
|
||||
* @return True if item is processable by this delegate.
|
||||
*/
|
||||
public boolean isForViewType(@NonNull final Object item, final int adapterPosition, final int collectionPosition) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(@NonNull final List<Object> items, final int adapterPosition, final int collectionPosition) {
|
||||
//noinspection unchecked
|
||||
return getItemId((TItem) items.get(collectionPosition), adapterPosition, collectionPosition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns unique ID of item to support stable ID's logic of RecyclerView's adapter.
|
||||
*
|
||||
* @param item Item in adapter;
|
||||
* @param adapterPosition Position of item in adapter;
|
||||
* @param collectionPosition Position of item in collection that contains item;
|
||||
* @return Unique item ID.
|
||||
*/
|
||||
public long getItemId(@NonNull final TItem item, final int adapterPosition, final int collectionPosition) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(
|
||||
@NonNull final RecyclerView.ViewHolder holder,
|
||||
@NonNull final List<Object> items,
|
||||
final int adapterPosition,
|
||||
final int collectionPosition,
|
||||
@NonNull final List<Object> payloads
|
||||
) {
|
||||
//noinspection unchecked
|
||||
onBindViewHolder((TViewHolder) holder, (TItem) items.get(collectionPosition), adapterPosition, collectionPosition, payloads);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds item with payloads to created by this object ViewHolder.
|
||||
*
|
||||
* @param holder ViewHolder to bind item to;
|
||||
* @param item Item in adapter;
|
||||
* @param adapterPosition Position of item in adapter;
|
||||
* @param collectionPosition Position of item in collection that contains item;
|
||||
* @param payloads Payloads;
|
||||
*/
|
||||
public abstract void onBindViewHolder(
|
||||
@NonNull final TViewHolder holder,
|
||||
@NonNull final TItem item,
|
||||
final int adapterPosition,
|
||||
final int collectionPosition,
|
||||
@NonNull final List<Object> payloads
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package ru.touchin.roboswag.components.adapters
|
||||
|
||||
import android.support.v7.util.ListUpdateCallback
|
||||
import android.support.v7.widget.RecyclerView
|
||||
|
||||
class OffsetAdapterUpdateCallback(private val adapter: RecyclerView.Adapter<*>, private val offsetProvider: () -> Int) : ListUpdateCallback {
|
||||
|
||||
override fun onInserted(position: Int, count: Int) {
|
||||
adapter.notifyItemRangeInserted(position + offsetProvider(), count)
|
||||
}
|
||||
|
||||
override fun onRemoved(position: Int, count: Int) {
|
||||
adapter.notifyItemRangeRemoved(position + offsetProvider(), count)
|
||||
}
|
||||
|
||||
override fun onMoved(fromPosition: Int, toPosition: Int) {
|
||||
adapter.notifyItemMoved(fromPosition + offsetProvider(), toPosition + offsetProvider())
|
||||
}
|
||||
|
||||
override fun onChanged(position: Int, count: Int, payload: Any?) {
|
||||
adapter.notifyItemRangeChanged(position + offsetProvider(), count, payload)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package ru.touchin.roboswag.components.adapters;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Objects of such class controls creation and binding of specific type of RecyclerView's ViewHolders.
|
||||
* Such delegates are creating and binding ViewHolders by position in adapter.
|
||||
* Default {@link #getItemViewType} is generating on construction of object.
|
||||
*
|
||||
* @param <TViewHolder> Type of {@link RecyclerView.ViewHolder} of delegate.
|
||||
*/
|
||||
public abstract class PositionAdapterDelegate<TViewHolder extends RecyclerView.ViewHolder> extends AdapterDelegate<TViewHolder> {
|
||||
|
||||
@Override
|
||||
public boolean isForViewType(@NonNull final List<Object> items, final int adapterPosition, final int collectionPosition) {
|
||||
return isForViewType(adapterPosition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if object is processable by this delegate.
|
||||
*
|
||||
* @param adapterPosition Position of item in adapter;
|
||||
* @return True if item is processable by this delegate.
|
||||
*/
|
||||
public abstract boolean isForViewType(final int adapterPosition);
|
||||
|
||||
@Override
|
||||
public long getItemId(@NonNull final List<Object> objects, final int adapterPosition, final int itemsOffset) {
|
||||
return getItemId(adapterPosition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns unique ID of item to support stable ID's logic of RecyclerView's adapter.
|
||||
*
|
||||
* @param adapterPosition Position of item in adapter;
|
||||
* @return Unique item ID.
|
||||
*/
|
||||
public long getItemId(final int adapterPosition) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(
|
||||
@NonNull final RecyclerView.ViewHolder holder,
|
||||
@NonNull final List<Object> items,
|
||||
final int adapterPosition,
|
||||
final int collectionPosition,
|
||||
@NonNull final List<Object> payloads
|
||||
) {
|
||||
//noinspection unchecked
|
||||
onBindViewHolder((TViewHolder) holder, adapterPosition, payloads);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds position with payloads to ViewHolder.
|
||||
*
|
||||
* @param holder ViewHolder to bind position to;
|
||||
* @param adapterPosition Position of item in adapter;
|
||||
* @param payloads Payloads.
|
||||
*/
|
||||
public void onBindViewHolder(@NonNull final TViewHolder holder, final int adapterPosition, @NonNull final List<Object> payloads) {
|
||||
//do nothing by default
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -14,8 +14,8 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
api project(":components-utils")
|
||||
api project(":components-logging")
|
||||
api project(":utils")
|
||||
api project(":logging")
|
||||
|
||||
implementation "com.android.support:support-annotations:$versions.supportLibrary"
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
api project(":components-utils")
|
||||
api project(":components-logging")
|
||||
api project(":utils")
|
||||
api project(":logging")
|
||||
|
||||
implementation "com.android.support:design:$versions.supportLibrary"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue