diff options
15 files changed, 2 insertions, 1749 deletions
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/AdapterUtils.kt b/adapter/src/main/kotlin/ca/allanwang/kau/adapters/AdapterUtils.kt deleted file mode 100644 index 17fd09f..0000000 --- a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/AdapterUtils.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2018 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 -import com.mikepenz.fastadapter.IAdapter -import com.mikepenz.fastadapter.IAdapterExtension -import com.mikepenz.fastadapter.IItem -import com.mikepenz.fastadapter.select.SelectExtension - -/** - * Created by Allan Wang on 2017-11-08. - */ - -/** - * Add kotlin's generic syntax to better support out types - */ -fun <Item : IItem<*, *>> fastAdapter(vararg adapter: IAdapter<out Item>) = - FastAdapter.with<Item, IAdapter<out Item>>(adapter.toList())!! - -inline fun <reified T : IAdapterExtension<Item>, Item : IItem<*, *>> FastAdapter<Item>.getExtension(): T? = - getExtension(T::class.java) - -/** - * Returns selection size, or -1 if selection is disabled - */ -inline val <Item : IItem<*, *>> IAdapter<Item>.selectionSize: Int - get() = fastAdapter.getExtension<SelectExtension<Item>, Item>()?.selections?.size ?: -1 - -inline val <Item : IItem<*, *>> IAdapter<Item>.selectedItems: Set<Item> - get() = fastAdapter.getExtension<SelectExtension<Item>, Item>()?.selectedItems ?: emptySet() diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/FastItemThemedAdapter.kt b/adapter/src/main/kotlin/ca/allanwang/kau/adapters/FastItemThemedAdapter.kt deleted file mode 100644 index 152982f..0000000 --- a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/FastItemThemedAdapter.kt +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2018 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 android.content.res.ColorStateList -import android.os.Build -import android.view.View -import android.widget.ImageView -import android.widget.TextView -import androidx.annotation.RequiresApi -import ca.allanwang.kau.ui.createSimpleRippleDrawable -import ca.allanwang.kau.utils.adjustAlpha -import com.mikepenz.fastadapter.IItem -import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter - -/** - * Created by Allan Wang on 2017-06-29. - * - * Adapter with a set of colors that will be added to all subsequent items - * Changing a color while the adapter is not empty will reload all items - * - * This adapter overrides every method where an item is added - * If that item extends [ThemableIItem], then the colors will be set - */ -class FastItemThemedAdapter<Item : IItem<*, *>>( - textColor: Int? = null, - backgroundColor: Int? = null, - accentColor: Int? = null -) : FastItemAdapter<Item>() { - constructor(colors: ThemableIItemColors) : this(colors.textColor, colors.backgroundColor, colors.accentColor) - - var textColor: Int? = textColor - set(value) { - if (field == value) return - field = value - themeChanged() - } - var backgroundColor: Int? = backgroundColor - set(value) { - if (field == value) return - field = value - themeChanged() - } - var accentColor: Int? = accentColor - set(value) { - if (field == value) return - field = value - themeChanged() - } - - fun setColors(colors: ThemableIItemColors) { - this.textColor = colors.textColor - this.backgroundColor = colors.backgroundColor - this.accentColor = colors.accentColor - } - - fun themeChanged() { - if (adapterItemCount == 0) return - injectTheme(adapterItems) - notifyAdapterDataSetChanged() - } - - override fun add(position: Int, items: List<Item>): FastItemAdapter<Item> { - injectTheme(items) - return super.add(position, items) - } - - override fun add(position: Int, item: Item): FastItemAdapter<Item> { - injectTheme(item) - return super.add(position, item) - } - - override fun add(item: Item): FastItemAdapter<Item> { - injectTheme(item) - return super.add(item) - } - - override fun add(items: List<Item>?): FastItemAdapter<Item> { - injectTheme(items) - return super.add(items) - } - - override fun set(items: List<Item>?): FastItemAdapter<Item> { - injectTheme(items) - return super.set(items) - } - - override fun set(position: Int, item: Item): FastItemAdapter<Item> { - injectTheme(item) - return super.set(position, item) - } - - override fun setNewList(items: List<Item>?, retainFilter: Boolean): FastItemAdapter<Item> { - injectTheme(items) - return super.setNewList(items, retainFilter) - } - - override fun setNewList(items: List<Item>?): FastItemAdapter<Item> { - injectTheme(items) - return super.setNewList(items) - } - - private fun injectTheme(items: Collection<IItem<*, *>?>?) { - items?.forEach { injectTheme(it) } - } - - protected fun injectTheme(item: IItem<*, *>?) { - if (item is ThemableIItem && item.themeEnabled) { - item.textColor = textColor - item.backgroundColor = backgroundColor - item.accentColor = accentColor - } - } -} - -interface ThemableIItemColors { - var textColor: Int? - var backgroundColor: Int? - var accentColor: Int? -} - -class ThemableIItemColorsDelegate : ThemableIItemColors { - override var textColor: Int? = null - override var backgroundColor: Int? = null - override var accentColor: Int? = null -} - -/** - * Interface that needs to be implemented by every iitem - * Holds the color values and has helper methods to inject the colors - */ -interface ThemableIItem : ThemableIItemColors { - var themeEnabled: Boolean - fun bindTextColor(vararg views: TextView?) - fun bindTextColorSecondary(vararg views: TextView?) - fun bindDividerColor(vararg views: View?) - fun bindAccentColor(vararg views: TextView?) - fun bindBackgroundColor(vararg views: View?) - fun bindBackgroundRipple(vararg views: View?) - fun bindIconColor(vararg views: ImageView?) -} - -/** - * The delegate for [ThemableIItem] - */ -class ThemableIItemDelegate : ThemableIItem, ThemableIItemColors by ThemableIItemColorsDelegate() { - override var themeEnabled: Boolean = true - - override fun bindTextColor(vararg views: TextView?) { - val color = textColor ?: return - views.forEach { it?.setTextColor(color) } - } - - override fun bindTextColorSecondary(vararg views: TextView?) { - val color = textColor?.adjustAlpha(0.8f) ?: return - views.forEach { it?.setTextColor(color) } - } - - override fun bindAccentColor(vararg views: TextView?) { - val color = accentColor ?: textColor ?: return - views.forEach { it?.setTextColor(color) } - } - - override fun bindDividerColor(vararg views: View?) { - val color = (textColor ?: accentColor)?.adjustAlpha(0.1f) ?: return - views.forEach { it?.setBackgroundColor(color) } - } - - override fun bindBackgroundColor(vararg views: View?) { - val color = backgroundColor ?: return - views.forEach { it?.setBackgroundColor(color) } - } - - @RequiresApi(Build.VERSION_CODES.LOLLIPOP) - override fun bindBackgroundRipple(vararg views: View?) { - val background = backgroundColor ?: return - val foreground = accentColor ?: textColor ?: backgroundColor - ?: return //default to normal background - val ripple = createSimpleRippleDrawable(foreground, background) - views.forEach { it?.background = ripple } - } - - @RequiresApi(Build.VERSION_CODES.LOLLIPOP) - override fun bindIconColor(vararg views: ImageView?) { - val color = accentColor ?: textColor ?: return - views.forEach { it?.drawable?.setTintList(ColorStateList.valueOf(color)) } - } -} diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/RepeatedClickListener.kt b/adapter/src/main/kotlin/ca/allanwang/kau/adapters/RepeatedClickListener.kt deleted file mode 100644 index 40b4774..0000000 --- a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/RepeatedClickListener.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2018 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 android.view.View -import androidx.annotation.IntRange -import com.mikepenz.fastadapter.FastAdapter -import com.mikepenz.fastadapter.IAdapter -import com.mikepenz.fastadapter.IItem -import com.mikepenz.fastadapter.listeners.OnClickListener - -/** - * Created by Allan Wang on 26/12/17. - */ -fun <Item : IItem<*, *>> FastAdapter<Item>.withOnRepeatedClickListener( - count: Int, - duration: Long, - event: OnClickListener<Item> -) = - withOnClickListener(RepeatedClickListener(count, duration, event)) - -/** - * Registers and skips each click until the designated [count] clicks are triggered, - * each within [duration] from each other. - * Only then will the [event] be fired, and everything will be reset. - */ -private class RepeatedClickListener<Item : IItem<*, *>>( - @IntRange(from = 1) val count: Int, - @IntRange(from = 1) val duration: Long, - val event: OnClickListener<Item> -) : OnClickListener<Item> { - - init { - if (count <= 0) - throw IllegalArgumentException("RepeatedClickListener's count must be > 1") - if (duration <= 0) - throw IllegalArgumentException("RepeatedClickListener's duration must be > 1L") - } - - private var chain = 0 - private var time = -1L - - override fun onClick(v: View?, adapter: IAdapter<Item>, item: Item, position: Int): Boolean { - val now = System.currentTimeMillis() - if (time - now < duration) - chain++ - else - chain = 1 - time = now - if (chain == count) { - chain = 0 - event.onClick(v, adapter, item, position) - return true - } - return false - } -} diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt deleted file mode 100644 index 6e33833..0000000 --- a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2018 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.iitems - -import android.graphics.Color -import android.graphics.drawable.Drawable -import android.view.View -import android.widget.Button -import android.widget.ImageView -import android.widget.LinearLayout -import android.widget.TextView -import androidx.cardview.widget.CardView -import androidx.recyclerview.widget.RecyclerView -import ca.allanwang.kau.adapter.R -import ca.allanwang.kau.adapters.ThemableIItem -import ca.allanwang.kau.adapters.ThemableIItemDelegate -import ca.allanwang.kau.utils.INVALID_ID -import ca.allanwang.kau.utils.drawable -import ca.allanwang.kau.utils.gone -import ca.allanwang.kau.utils.string -import ca.allanwang.kau.utils.toDrawable -import ca.allanwang.kau.utils.visible -import com.mikepenz.fastadapter.FastAdapter -import com.mikepenz.fastadapter.IItem -import com.mikepenz.fastadapter.listeners.ClickEventHook -import com.mikepenz.iconics.typeface.IIcon - -/** - * Created by Allan Wang on 2017-06-28. - * - * Simple generic card item with an icon, title, description and button - * The icon and button are hidden by default unless values are given - */ -class CardIItem( - val builder: Config.() -> Unit = {} -) : KauIItem<CardIItem, CardIItem.ViewHolder>( - R.layout.kau_iitem_card, ::ViewHolder, R.id.kau_item_card -), ThemableIItem by ThemableIItemDelegate() { - - companion object { - fun bindClickEvents(fastAdapter: FastAdapter<IItem<*, *>>) { - fastAdapter.withEventHook(object : ClickEventHook<IItem<*, *>>() { - override fun onBindMany(viewHolder: RecyclerView.ViewHolder): List<View>? { - return if (viewHolder is ViewHolder) listOf(viewHolder.card, viewHolder.button) else null - } - - override fun onClick(v: View, position: Int, adapter: FastAdapter<IItem<*, *>>, item: IItem<*, *>) { - if (item !is CardIItem) return - with(item.configs) { - when (v.id) { - R.id.kau_card_container -> cardClick?.invoke() - R.id.kau_card_button -> buttonClick?.invoke() - else -> { - } - } - } - } - }) - } - } - - val configs = Config().apply { builder() } - - class Config { - var title: String? = null - var titleRes: Int = INVALID_ID - var desc: String? = null - var descRes: Int = INVALID_ID - var button: String? = null - var buttonRes: Int = INVALID_ID - var buttonClick: (() -> Unit)? = null - var cardClick: (() -> Unit)? = null - var image: Drawable? = null - var imageIIcon: IIcon? = null - var imageIIconColor: Int = Color.WHITE - var imageRes: Int = INVALID_ID - } - - override fun bindView(holder: ViewHolder, payloads: MutableList<Any>) { - super.bindView(holder, payloads) - with(holder.itemView.context) context@{ - with(configs) { - holder.title.text = string(titleRes, title) - val descText = string(descRes, desc) - if (descText != null) holder.description.visible().text = descText - val buttonText = string(buttonRes, button) - if (buttonText != null) { - holder.bottomRow.visible() - holder.button.text = buttonText - } - val icon = drawable(imageRes) { - imageIIcon?.toDrawable(this@context, sizeDp = 24, color = imageIIconColor) - ?: image - } - if (icon != null) holder.icon.visible().setImageDrawable(icon) - } - with(holder) { - bindTextColor(title) - bindTextColorSecondary(description) - bindAccentColor(button) - if (configs.imageIIcon != null) bindIconColor(icon) - bindBackgroundRipple(card) - } - } - } - - override fun unbindView(holder: ViewHolder) { - super.unbindView(holder) - with(holder) { - icon.gone().setImageDrawable(null) - title.text = null - description.gone().text = null - bottomRow.gone() - button.setOnClickListener(null) - card.setOnClickListener(null) - } - } - - class ViewHolder(v: View) : RecyclerView.ViewHolder(v) { - val card: CardView = v.findViewById(R.id.kau_card_container) - val icon: ImageView = v.findViewById(R.id.kau_card_image) - val title: TextView = v.findViewById(R.id.kau_card_title) - val description: TextView = v.findViewById(R.id.kau_card_description) - val bottomRow: LinearLayout = v.findViewById(R.id.kau_card_bottom_row) - val button: Button = v.findViewById(R.id.kau_card_button) - } -} diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt deleted file mode 100644 index 2c488b1..0000000 --- a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2018 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.iitems - -import android.view.View -import android.widget.TextView -import androidx.cardview.widget.CardView -import androidx.recyclerview.widget.RecyclerView -import ca.allanwang.kau.adapter.R -import ca.allanwang.kau.adapters.ThemableIItem -import ca.allanwang.kau.adapters.ThemableIItemDelegate -import ca.allanwang.kau.utils.INVALID_ID -import ca.allanwang.kau.utils.string - -/** - * Created by Allan Wang on 2017-06-28. - * - * Simple Header with lots of padding on the top - * Contains only one text view - */ -class HeaderIItem( - text: String? = null, - var textRes: Int = INVALID_ID -) : KauIItem<HeaderIItem, HeaderIItem.ViewHolder>( - R.layout.kau_iitem_header, { ViewHolder(it) }, R.id.kau_item_header_big_margin_top -), ThemableIItem by ThemableIItemDelegate() { - - var text: String = text ?: "Header Placeholder" - - override fun bindView(holder: ViewHolder, payloads: MutableList<Any>) { - super.bindView(holder, payloads) - holder.text.text = holder.itemView.context.string(textRes, text) - bindTextColor(holder.text) - bindBackgroundColor(holder.container) - } - - override fun unbindView(holder: ViewHolder) { - super.unbindView(holder) - holder.text.text = null - } - - class ViewHolder(v: View) : RecyclerView.ViewHolder(v) { - val text: TextView = v.findViewById(R.id.kau_header_text) - val container: CardView = v.findViewById(R.id.kau_header_container) - } -} diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/KauIItem.kt b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/KauIItem.kt deleted file mode 100644 index c66dc01..0000000 --- a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/KauIItem.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2018 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.iitems - -import android.annotation.SuppressLint -import android.view.View -import androidx.annotation.LayoutRes -import androidx.recyclerview.widget.RecyclerView -import com.mikepenz.fastadapter.IClickable -import com.mikepenz.fastadapter.IItem -import com.mikepenz.fastadapter.items.AbstractItem - -/** - * Created by Allan Wang on 2017-07-03. - * - * Kotlin implementation of the [AbstractItem] to make things shorter - * If only one iitem type extends the given [layoutRes], you may use it as the type and not worry about another id - */ -open class KauIItem<Item, VH : RecyclerView.ViewHolder>( - @param:LayoutRes private val layoutRes: Int, - private val viewHolder: (v: View) -> VH, - private val type: Int = layoutRes -) : AbstractItem<Item, VH>() where Item : IItem<*, *>, Item : IClickable<*> { - @SuppressLint("ResourceType") - final override fun getType(): Int = type - - final override fun getViewHolder(v: View): VH = viewHolder(v) - final override fun getLayoutRes(): Int = layoutRes -} diff --git a/fastadapter/build.gradle b/fastadapter/build.gradle index 86fd084..9fd848e 100644 --- a/fastadapter/build.gradle +++ b/fastadapter/build.gradle @@ -3,6 +3,7 @@ ext.kauSubModuleMinSdk = kau.Versions.coreMinSdk apply from: '../android-lib.gradle' dependencies { + implementation project(':core') api project(':adapter') api kau.Dependencies.fastAdapter diff --git a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/AnimatorInterfaces.kt b/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/AnimatorInterfaces.kt deleted file mode 100644 index b83a2d0..0000000 --- a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/AnimatorInterfaces.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2018 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.animators - -import android.view.View -import android.view.ViewPropertyAnimator -import androidx.recyclerview.widget.RecyclerView - -/** - * Created by Allan Wang on 2017-07-11. - */ -class KauAnimatorException(message: String) : RuntimeException(message) - -interface KauAnimatorAdd { - fun animationPrepare(holder: RecyclerView.ViewHolder): View.() -> Unit - fun animation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit - fun animationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit - fun getDelay(remove: Long, move: Long, change: Long): Long - var itemDelayFactor: Float -} - -interface KauAnimatorRemove { - fun animation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit - fun animationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit - fun getDelay(remove: Long, move: Long, change: Long): Long - var itemDelayFactor: Float -} - -interface KauAnimatorChange { - fun changeOldAnimation( - holder: RecyclerView.ViewHolder, - changeInfo: BaseItemAnimator.ChangeInfo - ): ViewPropertyAnimator.() -> Unit - - fun changeNewAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit - fun changeAnimationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit -} diff --git a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/BaseItemAnimator.java b/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/BaseItemAnimator.java deleted file mode 100644 index 4ead735..0000000 --- a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/BaseItemAnimator.java +++ /dev/null @@ -1,765 +0,0 @@ -package ca.allanwang.kau.animators; - -/* - * Created by Allan Wang on 2017-06-27. - * - * Based on Item Animator by {@author Mike Penz} - * Rewritten to match with the updated compat dependencies - */ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * 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. - */ - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.TimeInterpolator; -import android.animation.ValueAnimator; -import androidx.annotation.NonNull; -import androidx.core.view.ViewCompat; -import androidx.recyclerview.widget.RecyclerView.ViewHolder; -import androidx.recyclerview.widget.SimpleItemAnimator; - -import android.view.View; -import android.view.ViewPropertyAnimator; -import android.view.animation.Interpolator; - -import java.util.ArrayList; -import java.util.List; - -/** - * This implementation of {@link androidx.recyclerview.widget.RecyclerView.ItemAnimator} provides basic - * animations on remove, add, and move events that happen to the items in - * a RecyclerView. RecyclerView uses a DefaultItemAnimator by default. - * - * @see androidx.recyclerview.widget.RecyclerView#setItemAnimator(androidx.recyclerview.widget.RecyclerView.ItemAnimator) - */ -public abstract class BaseItemAnimator extends SimpleItemAnimator { - private static final boolean DEBUG = false; - - private static TimeInterpolator sDefaultInterpolator; - - private ArrayList<ViewHolder> mPendingRemovals = new ArrayList<>(); - private ArrayList<ViewHolder> mPendingAdditions = new ArrayList<>(); - private ArrayList<MoveInfo> mPendingMoves = new ArrayList<>(); - private ArrayList<ChangeInfo> mPendingChanges = new ArrayList<>(); - - ArrayList<ArrayList<ViewHolder>> mAdditionsList = new ArrayList<>(); - ArrayList<ArrayList<MoveInfo>> mMovesList = new ArrayList<>(); - ArrayList<ArrayList<ChangeInfo>> mChangesList = new ArrayList<>(); - - ArrayList<ViewHolder> mAddAnimations = new ArrayList<>(); - ArrayList<ViewHolder> mMoveAnimations = new ArrayList<>(); - ArrayList<ViewHolder> mRemoveAnimations = new ArrayList<>(); - ArrayList<ViewHolder> mChangeAnimations = new ArrayList<>(); - - public Interpolator interpolator; - - private static class MoveInfo { - public ViewHolder holder; - public int fromX, fromY, toX, toY; - - MoveInfo(ViewHolder holder, int fromX, int fromY, int toX, int toY) { - this.holder = holder; - this.fromX = fromX; - this.fromY = fromY; - this.toX = toX; - this.toY = toY; - } - } - - public static class ChangeInfo { - public ViewHolder oldHolder, newHolder; - public int fromX, fromY, toX, toY; - - private ChangeInfo(ViewHolder oldHolder, ViewHolder newHolder) { - this.oldHolder = oldHolder; - this.newHolder = newHolder; - } - - ChangeInfo(ViewHolder oldHolder, ViewHolder newHolder, - int fromX, int fromY, int toX, int toY) { - this(oldHolder, newHolder); - this.fromX = fromX; - this.fromY = fromY; - this.toX = toX; - this.toY = toY; - } - - @Override - public String toString() { - return "ChangeInfo{" - + "oldHolder=" + oldHolder - + ", newHolder=" + newHolder - + ", fromX=" + fromX - + ", fromY=" + fromY - + ", toX=" + toX - + ", toY=" + toY - + '}'; - } - } - - @Override - public void runPendingAnimations() { - boolean removalsPending = !mPendingRemovals.isEmpty(); - boolean movesPending = !mPendingMoves.isEmpty(); - boolean changesPending = !mPendingChanges.isEmpty(); - boolean additionsPending = !mPendingAdditions.isEmpty(); - if (!removalsPending && !movesPending && !additionsPending && !changesPending) { - // nothing to animate - return; - } - // First, remove stuff - for (ViewHolder holder : mPendingRemovals) { - animateRemoveImpl(holder); - } - mPendingRemovals.clear(); - // Next, move stuff - if (movesPending) { - final ArrayList<MoveInfo> moves = new ArrayList<>(); - moves.addAll(mPendingMoves); - mMovesList.add(moves); - mPendingMoves.clear(); - Runnable mover = new Runnable() { - @Override - public void run() { - for (MoveInfo moveInfo : moves) { - animateMoveImpl(moveInfo.holder, moveInfo.fromX, moveInfo.fromY, - moveInfo.toX, moveInfo.toY); - } - moves.clear(); - mMovesList.remove(moves); - } - }; - if (removalsPending) { - View view = moves.get(0).holder.itemView; - ViewCompat.postOnAnimationDelayed(view, mover, 0); - } else { - mover.run(); - } - } - // Next, change stuff, to run in parallel with move animations - if (changesPending) { - final ArrayList<ChangeInfo> changes = new ArrayList<>(); - changes.addAll(mPendingChanges); - mChangesList.add(changes); - mPendingChanges.clear(); - Runnable changer = new Runnable() { - @Override - public void run() { - for (ChangeInfo change : changes) { - animateChangeImpl(change); - } - changes.clear(); - mChangesList.remove(changes); - } - }; - if (removalsPending) { - ViewHolder holder = changes.get(0).oldHolder; - long moveDuration = movesPending ? getMoveDuration() : 0; - ViewCompat.postOnAnimationDelayed(holder.itemView, changer, getRemoveDelay(getRemoveDuration(), moveDuration, getChangeDuration())); - } else { - changer.run(); - } - } - // Next, add stuff - if (additionsPending) { - final ArrayList<ViewHolder> additions = new ArrayList<>(); - additions.addAll(mPendingAdditions); - mAdditionsList.add(additions); - mPendingAdditions.clear(); - Runnable adder = new Runnable() { - @Override - public void run() { - for (ViewHolder holder : additions) { - animateAddImpl(holder); - } - additions.clear(); - mAdditionsList.remove(additions); - } - }; - if (removalsPending || movesPending || changesPending) { - long removeDuration = removalsPending ? getRemoveDuration() : 0; - long moveDuration = movesPending ? getMoveDuration() : 0; - long changeDuration = changesPending ? getChangeDuration() : 0; - View view = additions.get(0).itemView; - ViewCompat.postOnAnimationDelayed(view, adder, getAddDelay(removeDuration, moveDuration, changeDuration)); - } else { - adder.run(); - } - } - } - - /** - * used to calculated the delay until the remove animation should start - * - * @param remove the remove duration - * @param move the move duration - * @param change the change duration - * @return the calculated delay for the remove items animation - */ - public long getRemoveDelay(long remove, long move, long change) { - return remove + Math.max(move, change); - } - - /** - * used to calculated the delay until the add animation should start - * - * @param remove the remove duration - * @param move the move duration - * @param change the change duration - * @return the calculated delay for the add items animation - */ - public long getAddDelay(long remove, long move, long change) { - return remove + Math.max(move, change); - } - - @Override - public boolean animateRemove(final ViewHolder holder) { - resetAnimation(holder); - mPendingRemovals.add(holder); - return true; - } - - private void animateRemoveImpl(final ViewHolder holder) { - final ViewPropertyAnimator animation = removeAnimation(holder); - mRemoveAnimations.add(holder); - animation.setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animator) { - dispatchRemoveStarting(holder); - } - - @Override - public void onAnimationEnd(Animator animator) { - animation.setListener(null); - removeAnimationCleanup(holder); - dispatchRemoveFinished(holder); - mRemoveAnimations.remove(holder); - dispatchFinishedWhenDone(); - } - }).start(); - } - - abstract public ViewPropertyAnimator removeAnimation(ViewHolder holder); - - abstract public void removeAnimationCleanup(ViewHolder holder); - - @Override - public boolean animateAdd(final ViewHolder holder) { - resetAnimation(holder); - addAnimationPrepare(holder); - mPendingAdditions.add(holder); - return true; - } - - void animateAddImpl(final ViewHolder holder) { - final ViewPropertyAnimator animation = addAnimation(holder); - mAddAnimations.add(holder); - animation.setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animator) { - dispatchAddStarting(holder); - } - - @Override - public void onAnimationCancel(Animator animator) { - addAnimationCleanup(holder); - } - - @Override - public void onAnimationEnd(Animator animator) { - animation.setListener(null); - dispatchAddFinished(holder); - mAddAnimations.remove(holder); - dispatchFinishedWhenDone(); - addAnimationCleanup(holder); - } - }).start(); - } - - /** - * the animation to prepare the view before the add animation is run - * - * @param holder - */ - public abstract void addAnimationPrepare(ViewHolder holder); - - /** - * the animation for adding a view - * - * @param holder - * @return - */ - public abstract ViewPropertyAnimator addAnimation(ViewHolder holder); - - /** - * the cleanup method if the animation needs to be stopped. and tro prepare for the next view - * - * @param holder - */ - abstract void addAnimationCleanup(ViewHolder holder); - - @Override - public boolean animateMove(final ViewHolder holder, int fromX, int fromY, - int toX, int toY) { - final View view = holder.itemView; - fromX += (int) holder.itemView.getTranslationX(); - fromY += (int) holder.itemView.getTranslationY(); - resetAnimation(holder); - int deltaX = toX - fromX; - int deltaY = toY - fromY; - if (deltaX == 0 && deltaY == 0) { - dispatchMoveFinished(holder); - return false; - } - if (deltaX != 0) { - view.setTranslationX(-deltaX); - } - if (deltaY != 0) { - view.setTranslationY(-deltaY); - } - mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY)); - return true; - } - - void animateMoveImpl(final ViewHolder holder, int fromX, int fromY, int toX, int toY) { - final View view = holder.itemView; - final int deltaX = toX - fromX; - final int deltaY = toY - fromY; - if (deltaX != 0) { - view.animate().translationX(0); - } - if (deltaY != 0) { - view.animate().translationY(0); - } - // TODO: make EndActions end listeners instead, since end actions aren't called when - // vpas are canceled (and can't end them. why?) - // need listener functionality in VPACompat for this. Ick. - final ViewPropertyAnimator animation = view.animate(); - mMoveAnimations.add(holder); - animation.setDuration(getMoveDuration()).setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animator) { - dispatchMoveStarting(holder); - } - - @Override - public void onAnimationCancel(Animator animator) { - if (deltaX != 0) { - view.setTranslationX(0); - } - if (deltaY != 0) { - view.setTranslationY(0); - } - } - - @Override - public void onAnimationEnd(Animator animator) { - animation.setListener(null); - dispatchMoveFinished(holder); - mMoveAnimations.remove(holder); - dispatchFinishedWhenDone(); - } - }).start(); - } - - @Override - public boolean animateChange(ViewHolder oldHolder, ViewHolder newHolder, - int fromX, int fromY, int toX, int toY) { - if (oldHolder == newHolder) { - // Don't know how to run change animations when the same view holder is re-used. - // run a move animation to handle position changes. - return animateMove(oldHolder, fromX, fromY, toX, toY); - } - changeAnimation(oldHolder, newHolder, - fromX, fromY, toX, toY); - mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY)); - return true; - } - - void animateChangeImpl(final ChangeInfo changeInfo) { - final ViewHolder holder = changeInfo.oldHolder; - final View view = holder == null ? null : holder.itemView; - final ViewHolder newHolder = changeInfo.newHolder; - final View newView = newHolder != null ? newHolder.itemView : null; - if (view != null) { - final ViewPropertyAnimator oldViewAnim = changeOldAnimation(holder, changeInfo); - mChangeAnimations.add(changeInfo.oldHolder); - oldViewAnim.setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animator) { - dispatchChangeStarting(changeInfo.oldHolder, true); - } - - @Override - public void onAnimationEnd(Animator animator) { - oldViewAnim.setListener(null); - changeAnimationCleanup(holder); - view.setTranslationX(0); - view.setTranslationY(0); - dispatchChangeFinished(changeInfo.oldHolder, true); - mChangeAnimations.remove(changeInfo.oldHolder); - dispatchFinishedWhenDone(); - } - }).start(); - } - if (newView != null) { - final ViewPropertyAnimator newViewAnimation = changeNewAnimation(newHolder); - mChangeAnimations.add(changeInfo.newHolder); - newViewAnimation.setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animator) { - dispatchChangeStarting(changeInfo.newHolder, false); - } - - @Override - public void onAnimationEnd(Animator animator) { - newViewAnimation.setListener(null); - changeAnimationCleanup(newHolder); - newView.setTranslationX(0); - newView.setTranslationY(0); - dispatchChangeFinished(changeInfo.newHolder, false); - mChangeAnimations.remove(changeInfo.newHolder); - dispatchFinishedWhenDone(); - } - }).start(); - } - } - - /** - * the whole change animation if we have to cross animate two views - * - * @param oldHolder - * @param newHolder - * @param fromX - * @param fromY - * @param toX - * @param toY - */ - public void changeAnimation(ViewHolder oldHolder, ViewHolder newHolder, int fromX, int fromY, int toX, int toY) { - final float prevTranslationX = oldHolder.itemView.getTranslationX(); - final float prevTranslationY = oldHolder.itemView.getTranslationY(); - final float prevValue = oldHolder.itemView.getAlpha(); - resetAnimation(oldHolder); - int deltaX = (int) (toX - fromX - prevTranslationX); - int deltaY = (int) (toY - fromY - prevTranslationY); - // recover prev translation state after ending animation - oldHolder.itemView.setTranslationX(prevTranslationX); - oldHolder.itemView.setTranslationY(prevTranslationY); - - oldHolder.itemView.setAlpha(prevValue); - if (newHolder != null) { - // carry over translation values - resetAnimation(newHolder); - newHolder.itemView.setTranslationX(-deltaX); - newHolder.itemView.setTranslationY(-deltaY); - newHolder.itemView.setAlpha(0); - } - } - - /** - * the animation for removing the old view - * - * @param holder - * @return - */ - public abstract ViewPropertyAnimator changeOldAnimation(ViewHolder holder, ChangeInfo changeInfo); - - /** - * the animation for changing the new view - * - * @param holder - * @return - */ - public abstract ViewPropertyAnimator changeNewAnimation(ViewHolder holder); - - /** - * the cleanup method if the animation needs to be stopped. and to prepare for the next view - * - * @param holder - */ - public abstract void changeAnimationCleanup(ViewHolder holder); - - private void endChangeAnimation(List<ChangeInfo> infoList, ViewHolder item) { - for (int i = infoList.size() - 1; i >= 0; i--) { - ChangeInfo changeInfo = infoList.get(i); - if (endChangeAnimationIfNecessary(changeInfo, item)) { - if (changeInfo.oldHolder == null && changeInfo.newHolder == null) { - infoList.remove(changeInfo); - } - } - } - } - - private void endChangeAnimationIfNecessary(ChangeInfo changeInfo) { - if (changeInfo.oldHolder != null) { - endChangeAnimationIfNecessary(changeInfo, changeInfo.oldHolder); - } - if (changeInfo.newHolder != null) { - endChangeAnimationIfNecessary(changeInfo, changeInfo.newHolder); - } - } - - private boolean endChangeAnimationIfNecessary(ChangeInfo changeInfo, ViewHolder item) { - boolean oldItem = false; - if (changeInfo.newHolder == item) { - changeInfo.newHolder = null; - } else if (changeInfo.oldHolder == item) { - changeInfo.oldHolder = null; - oldItem = true; - } else { - return false; - } - changeAnimationCleanup(item); - item.itemView.setTranslationX(0); - item.itemView.setTranslationY(0); - dispatchChangeFinished(item, oldItem); - return true; - } - - @Override - public void endAnimation(ViewHolder item) { - final View view = item.itemView; - // this will trigger end callback which should set properties to their target values. - view.animate().cancel(); - // TODO if some other animations are chained to end, how do we cancel them as well? - for (int i = mPendingMoves.size() - 1; i >= 0; i--) { - MoveInfo moveInfo = mPendingMoves.get(i); - if (moveInfo.holder == item) { - view.setTranslationY(0); - view.setTranslationX(0); - dispatchMoveFinished(item); - mPendingMoves.remove(i); - } - } - endChangeAnimation(mPendingChanges, item); - if (mPendingRemovals.remove(item)) { - removeAnimationCleanup(item); - dispatchRemoveFinished(item); - } - if (mPendingAdditions.remove(item)) { - addAnimationCleanup(item); - dispatchAddFinished(item); - } - - for (int i = mChangesList.size() - 1; i >= 0; i--) { - ArrayList<ChangeInfo> changes = mChangesList.get(i); - endChangeAnimation(changes, item); - if (changes.isEmpty()) { - mChangesList.remove(i); - } - } - for (int i = mMovesList.size() - 1; i >= 0; i--) { - ArrayList<MoveInfo> moves = mMovesList.get(i); - for (int j = moves.size() - 1; j >= 0; j--) { - MoveInfo moveInfo = moves.get(j); - if (moveInfo.holder == item) { - view.setTranslationY(0); - view.setTranslationX(0); - dispatchMoveFinished(item); - moves.remove(j); - if (moves.isEmpty()) { - mMovesList.remove(i); - } - break; - } - } - } - for (int i = mAdditionsList.size() - 1; i >= 0; i--) { - ArrayList<ViewHolder> additions = mAdditionsList.get(i); - if (additions.remove(item)) { - addAnimationCleanup(item); - dispatchAddFinished(item); - if (additions.isEmpty()) { - mAdditionsList.remove(i); - } - } - } - - // animations should be ended by the cancel above. - //noinspection PointlessBooleanExpression,ConstantConditions - if (mRemoveAnimations.remove(item) && DEBUG) { - throw new IllegalStateException("after animation is cancelled, item should not be in " - + "mRemoveAnimations list"); - } - - //noinspection PointlessBooleanExpression,ConstantConditions - if (mAddAnimations.remove(item) && DEBUG) { - throw new IllegalStateException("after animation is cancelled, item should not be in " - + "mAddAnimations list"); - } - - //noinspection PointlessBooleanExpression,ConstantConditions - if (mChangeAnimations.remove(item) && DEBUG) { - throw new IllegalStateException("after animation is cancelled, item should not be in " - + "mChangeAnimations list"); - } - - //noinspection PointlessBooleanExpression,ConstantConditions - if (mMoveAnimations.remove(item) && DEBUG) { - throw new IllegalStateException("after animation is cancelled, item should not be in " - + "mMoveAnimations list"); - } - dispatchFinishedWhenDone(); - } - - private void resetAnimation(ViewHolder holder) { - - if (sDefaultInterpolator == null) { - sDefaultInterpolator = new ValueAnimator().getInterpolator(); - } - holder.itemView.animate().setInterpolator(sDefaultInterpolator); - endAnimation(holder); - } - - @Override - public boolean isRunning() { - return (!mPendingAdditions.isEmpty() - || !mPendingChanges.isEmpty() - || !mPendingMoves.isEmpty() - || !mPendingRemovals.isEmpty() - || !mMoveAnimations.isEmpty() - || !mRemoveAnimations.isEmpty() - || !mAddAnimations.isEmpty() - || !mChangeAnimations.isEmpty() - || !mMovesList.isEmpty() - || !mAdditionsList.isEmpty() - || !mChangesList.isEmpty()); - } - - /** - * Check the state of currently pending and running animations. If there are none - * pending/running, call {@link #dispatchAnimationsFinished()} to notify any - * listeners. - */ - void dispatchFinishedWhenDone() { - if (!isRunning()) { - dispatchAnimationsFinished(); - } - } - - @Override - public void endAnimations() { - int count = mPendingMoves.size(); - for (int i = count - 1; i >= 0; i--) { - MoveInfo item = mPendingMoves.get(i); - View view = item.holder.itemView; - view.setTranslationY(0); - view.setTranslationX(0); - dispatchMoveFinished(item.holder); - mPendingMoves.remove(i); - } - count = mPendingRemovals.size(); - for (int i = count - 1; i >= 0; i--) { - ViewHolder item = mPendingRemovals.get(i); - dispatchRemoveFinished(item); - mPendingRemovals.remove(i); - } - count = mPendingAdditions.size(); - for (int i = count - 1; i >= 0; i--) { - ViewHolder item = mPendingAdditions.get(i); - addAnimationCleanup(item); - dispatchAddFinished(item); - mPendingAdditions.remove(i); - } - count = mPendingChanges.size(); - for (int i = count - 1; i >= 0; i--) { - endChangeAnimationIfNecessary(mPendingChanges.get(i)); - } - mPendingChanges.clear(); - if (!isRunning()) { - return; - } - - int listCount = mMovesList.size(); - for (int i = listCount - 1; i >= 0; i--) { - ArrayList<MoveInfo> moves = mMovesList.get(i); - count = moves.size(); - for (int j = count - 1; j >= 0; j--) { - MoveInfo moveInfo = moves.get(j); - ViewHolder item = moveInfo.holder; - View view = item.itemView; - view.setTranslationY(0); - view.setTranslationX(0); - dispatchMoveFinished(moveInfo.holder); - moves.remove(j); - if (moves.isEmpty()) { - mMovesList.remove(moves); - } - } - } - listCount = mAdditionsList.size(); - for (int i = listCount - 1; i >= 0; i--) { - ArrayList<ViewHolder> additions = mAdditionsList.get(i); - count = additions.size(); - for (int j = count - 1; j >= 0; j--) { - ViewHolder item = additions.get(j); - View view = item.itemView; - addAnimationCleanup(item); - dispatchAddFinished(item); - additions.remove(j); - if (additions.isEmpty()) { - mAdditionsList.remove(additions); - } - } - } - listCount = mChangesList.size(); - for (int i = listCount - 1; i >= 0; i--) { - ArrayList<ChangeInfo> changes = mChangesList.get(i); - count = changes.size(); - for (int j = count - 1; j >= 0; j--) { - endChangeAnimationIfNecessary(changes.get(j)); - if (changes.isEmpty()) { - mChangesList.remove(changes); - } - } - } - - cancelAll(mRemoveAnimations); - cancelAll(mMoveAnimations); - cancelAll(mAddAnimations); - cancelAll(mChangeAnimations); - - dispatchAnimationsFinished(); - } - - void cancelAll(List<ViewHolder> viewHolders) { - for (int i = viewHolders.size() - 1; i >= 0; i--) { - viewHolders.get(i).itemView.animate().cancel(); - } - } - - /** - * {@inheritDoc} - * <p> - * If the payload list is not empty, DefaultItemAnimator returns <code>true</code>. - * When this is the case: - * <ul> - * <li>If you override {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)}, both - * ViewHolder arguments will be the same instance. - * </li> - * <li> - * If you are not overriding {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)}, - * then DefaultItemAnimator will call {@link #animateMove(ViewHolder, int, int, int, int)} and - * run a move animation instead. - * </li> - * </ul> - */ - @Override - public boolean canReuseUpdatedViewHolder(@NonNull ViewHolder viewHolder, - @NonNull List<Object> payloads) { - return !payloads.isEmpty() || super.canReuseUpdatedViewHolder(viewHolder, payloads); - } -} diff --git a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/DefaultAnimator.kt b/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/DefaultAnimator.kt deleted file mode 100644 index 4e342ab..0000000 --- a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/DefaultAnimator.kt +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2018 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.animators - -import android.view.ViewPropertyAnimator -import androidx.recyclerview.widget.RecyclerView - -/** - * Created by Allan Wang on 2017-06-27. - */ -open class DefaultAnimator : BaseItemAnimator() { - - override fun removeAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator { - return holder.itemView.animate().apply { - alpha(0f) - duration = this@DefaultAnimator.removeDuration - interpolator = this@DefaultAnimator.interpolator - } - } - - override fun removeAnimationCleanup(holder: RecyclerView.ViewHolder) { - holder.itemView.alpha = 1f - } - - override fun addAnimationPrepare(holder: RecyclerView.ViewHolder) { - holder.itemView.alpha = 0f - } - - override fun addAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator { - return holder.itemView.animate().apply { - alpha(1f) - duration = this@DefaultAnimator.addDuration - interpolator = this@DefaultAnimator.interpolator - } - } - - override fun addAnimationCleanup(holder: RecyclerView.ViewHolder) { - holder.itemView.alpha = 1f - } - - override fun changeOldAnimation(holder: RecyclerView.ViewHolder, changeInfo: ChangeInfo): ViewPropertyAnimator { - return holder.itemView.animate().apply { - alpha(0f) - translationX(changeInfo.toX.toFloat() - changeInfo.fromX) - translationY(changeInfo.toY.toFloat() - changeInfo.fromY) - duration = this@DefaultAnimator.changeDuration - interpolator = this@DefaultAnimator.interpolator - } - } - - override fun changeNewAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator { - return holder.itemView.animate().apply { - alpha(1f) - translationX(0f) - translationY(0f) - duration = this@DefaultAnimator.changeDuration - interpolator = this@DefaultAnimator.interpolator - } - } - - override fun changeAnimationCleanup(holder: RecyclerView.ViewHolder) { - holder.itemView.alpha = 1f - } -} diff --git a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/FadeScaleAnimator.kt b/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/FadeScaleAnimator.kt deleted file mode 100644 index 9113b0e..0000000 --- a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/FadeScaleAnimator.kt +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2018 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.animators - -import android.view.View -import android.view.ViewPropertyAnimator -import androidx.recyclerview.widget.RecyclerView -import ca.allanwang.kau.utils.scaleXY - -/** - * Created by Allan Wang on 2017-07-11. - */ -class FadeScaleAnimatorAdd(val scaleFactor: Float = 1.0f, override var itemDelayFactor: Float = 0.125f) : - KauAnimatorAdd { - - override fun animationPrepare(holder: RecyclerView.ViewHolder): View.() -> Unit = { - scaleXY = scaleFactor - alpha = 0f - } - - override fun animation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit = { - scaleXY(1f) - alpha(1f) - } - - override fun animationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit = { - scaleXY = 1f - alpha = 1f - } - - override fun getDelay(remove: Long, move: Long, change: Long): Long = 0L -} - -class FadeScaleAnimatorRemove(val scaleFactor: Float = 1.0f, override var itemDelayFactor: Float = 0.125f) : - KauAnimatorRemove { - - override fun animation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit = { - scaleXY(scaleFactor) - alpha(0f) - } - - override fun animationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit = { - scaleXY = 1f - alpha = 1f - } - - override fun getDelay(remove: Long, move: Long, change: Long): Long = 0L -} - -class FadeAnimatorChange : KauAnimatorChange { - - override fun changeOldAnimation( - holder: RecyclerView.ViewHolder, - changeInfo: BaseItemAnimator.ChangeInfo - ): ViewPropertyAnimator.() -> Unit = { alpha(0f) } - - override fun changeNewAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit = { alpha(1f) } - - override fun changeAnimationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit = { alpha = 1f } -} diff --git a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/KauAnimator.kt b/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/KauAnimator.kt deleted file mode 100644 index b9df946..0000000 --- a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/KauAnimator.kt +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2018 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.animators - -import android.view.ViewPropertyAnimator -import androidx.recyclerview.widget.RecyclerView -import ca.allanwang.kau.utils.KAU_BOTTOM -import ca.allanwang.kau.utils.KAU_RIGHT - -/** - * Created by Allan Wang on 2017-06-27. - */ -open class KauAnimator( - val addAnimator: KauAnimatorAdd = SlideAnimatorAdd(KAU_BOTTOM), - val removeAnimator: KauAnimatorRemove = SlideAnimatorRemove(KAU_RIGHT), - val changeAnimator: KauAnimatorChange = FadeAnimatorChange() -) : BaseItemAnimator() { - - open fun startDelay(holder: RecyclerView.ViewHolder, duration: Long, factor: Float) = - Math.max(0L, (holder.adapterPosition * duration * factor).toLong()) - - override fun removeAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator { - return holder.itemView.animate().apply { - startDelay = startDelay(holder, removeDuration, removeAnimator.itemDelayFactor) - duration = removeDuration - interpolator = this@KauAnimator.interpolator - removeAnimator.animation(holder)() - } - } - - override fun removeAnimationCleanup(holder: RecyclerView.ViewHolder) { - holder.itemView.apply { removeAnimator.animationCleanup(holder)() } - } - - override fun getRemoveDelay(remove: Long, move: Long, change: Long): Long = - removeAnimator.getDelay(remove, move, change) - - override fun addAnimationPrepare(holder: RecyclerView.ViewHolder) { - holder.itemView.apply { addAnimator.animationPrepare(holder)() } - } - - override fun addAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator { - return holder.itemView.animate().apply { - startDelay = startDelay(holder, addDuration, addAnimator.itemDelayFactor) - duration = addDuration - interpolator = this@KauAnimator.interpolator - addAnimator.animation(holder)() - } - } - - override fun addAnimationCleanup(holder: RecyclerView.ViewHolder) { - holder.itemView.apply { addAnimator.animationCleanup(holder)() } - } - - override fun getAddDelay(remove: Long, move: Long, change: Long): Long = addAnimator.getDelay(remove, move, change) - - override fun changeOldAnimation(holder: RecyclerView.ViewHolder, changeInfo: ChangeInfo): ViewPropertyAnimator { - return holder.itemView.animate().apply { - duration = changeDuration - interpolator = this@KauAnimator.interpolator - changeAnimator.changeOldAnimation(holder, changeInfo)() - } - } - - override fun changeNewAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator { - return holder.itemView.animate().apply { - duration = changeDuration - interpolator = this@KauAnimator.interpolator - changeAnimator.changeNewAnimation(holder)() - } - } - - override fun changeAnimationCleanup(holder: RecyclerView.ViewHolder) { - holder.itemView.apply { changeAnimator.changeAnimationCleanup(holder)() } - } -} diff --git a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/NoAnimator.kt b/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/NoAnimator.kt deleted file mode 100644 index cca8a25..0000000 --- a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/NoAnimator.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2018 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.animators - -import android.view.View -import android.view.ViewPropertyAnimator -import androidx.recyclerview.widget.RecyclerView - -/** - * Created by Allan Wang on 2017-08-02. - */ -class NoAnimatorAdd(override var itemDelayFactor: Float = 0f) : KauAnimatorAdd { - - override fun animationPrepare(holder: RecyclerView.ViewHolder): View.() -> Unit = {} - - override fun animation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit = {} - - override fun animationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit = { } - - override fun getDelay(remove: Long, move: Long, change: Long): Long = 0L -} - -class NoAnimatorRemove(override var itemDelayFactor: Float = 0f) : KauAnimatorRemove { - - override fun animation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit = { } - - override fun animationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit = {} - - override fun getDelay(remove: Long, move: Long, change: Long): Long = 0L -} - -class NoAnimatorChange : KauAnimatorChange { - - override fun changeOldAnimation( - holder: RecyclerView.ViewHolder, - changeInfo: BaseItemAnimator.ChangeInfo - ): ViewPropertyAnimator.() -> Unit = { } - - override fun changeNewAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit = { } - - override fun changeAnimationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit = { alpha = 1f } -} diff --git a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/SlideAnimator.kt b/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/SlideAnimator.kt deleted file mode 100644 index 55d5b2e..0000000 --- a/fastadapter/src/main/kotlin/ca/allanwang/kau/animators/SlideAnimator.kt +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2018 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.animators - -import android.view.View -import android.view.ViewPropertyAnimator -import androidx.recyclerview.widget.RecyclerView -import ca.allanwang.kau.utils.KAU_BOTTOM -import ca.allanwang.kau.utils.KAU_LEFT -import ca.allanwang.kau.utils.KAU_RIGHT -import ca.allanwang.kau.utils.KAU_TOP - -/** - * Created by Allan Wang on 2017-07-11. - */ -class SlideAnimatorAdd(val fromEdge: Int, val slideFactor: Float = 1f, override var itemDelayFactor: Float = 0.125f) : - KauAnimatorAdd { - - override fun animationPrepare(holder: RecyclerView.ViewHolder): View.() -> Unit = { - when (fromEdge) { - KAU_TOP -> translationY = slideFactor * -height - KAU_LEFT -> translationX = slideFactor * -width - KAU_BOTTOM -> translationY = slideFactor * height - KAU_RIGHT -> translationX = slideFactor * width - else -> throw KauAnimatorException("Invalid edge flag used in Slide Animator; use one of KAU_*") - } - alpha = 0f - } - - override fun animation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit = { - translationY(0f) - translationX(0f) - alpha(1f) - } - - override fun animationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit = { - translationY = 0f - translationX = 0f - alpha = 1f - } - - override fun getDelay(remove: Long, move: Long, change: Long): Long = 0L -} - -class SlideAnimatorRemove( - val fromEdge: Int, - val slideFactor: Float = 1f, - override var itemDelayFactor: Float = 0.125f -) : KauAnimatorRemove { - override fun animation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit = { - with(holder.itemView) { - when (fromEdge) { - KAU_TOP -> translationY(slideFactor * -height) - KAU_LEFT -> translationX(slideFactor * -width) - KAU_BOTTOM -> translationY(slideFactor * height) - KAU_RIGHT -> translationX(slideFactor * width) - else -> throw KauAnimatorException("Invalid edge flag used in Slide Animator; use one of KAU_*") - } - } - alpha(0f) - } - - override fun animationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit = { - translationY = 0f - translationX = 0f - alpha = 1f - } - - override fun getDelay(remove: Long, move: Long, change: Long): Long = 0L -} diff --git a/kpref-activity/build.gradle b/kpref-activity/build.gradle index e2e2771..5cce460 100644 --- a/kpref-activity/build.gradle +++ b/kpref-activity/build.gradle @@ -7,7 +7,7 @@ apply from: '../android-lib.gradle' dependencies { implementation project(':core') implementation project(':colorpicker') - implementation project(':adapter') + implementation project(':fastadapter') } apply from: '../artifacts.gradle' |