aboutsummaryrefslogtreecommitdiff
path: root/library/src/main/kotlin
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-06-29 16:16:15 -0700
committerAllan Wang <me@allanwang.ca>2017-06-29 16:16:15 -0700
commitbfb16f2d56dd4da8d302a924efb7ea119582fde0 (patch)
tree2fd6ae1f5ffe305ce761ad88609692c163e6ebb3 /library/src/main/kotlin
parent8f2e56eb5ecfc6b5ce2f1530ead6fe73f5bfe89c (diff)
downloadkau-bfb16f2d56dd4da8d302a924efb7ea119582fde0.tar.gz
kau-bfb16f2d56dd4da8d302a924efb7ea119582fde0.tar.bz2
kau-bfb16f2d56dd4da8d302a924efb7ea119582fde0.zip
Finalize about activity
Diffstat (limited to 'library/src/main/kotlin')
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt122
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/adapters/FastItemThemedAdapter.kt179
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/animators/BaseDelayAnimator.kt45
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/animators/BaseItemAnimator.java2
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/animators/BaseSlideAlphaAnimator.kt52
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/animators/DefaultAnimator.kt1
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/animators/FadeScaleAnimator.kt51
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/animators/SlideUpAlphaAnimator.kt52
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/animators/SlideUpExitRightAnimator.kt23
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/changelog/Changelog.kt29
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt13
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/iitems/CutoutIItem.kt6
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt49
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/iitems/LibraryIItem.kt36
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt3
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt27
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/widgets/ElasticDragDismissFrameLayout.kt4
-rw-r--r--library/src/main/kotlin/ca/allanwang/kau/widgets/InkPageIndicator.java9
18 files changed, 587 insertions, 116 deletions
diff --git a/library/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt b/library/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt
index 143e92a..d27f32f 100644
--- a/library/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt
+++ b/library/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt
@@ -11,7 +11,13 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import ca.allanwang.kau.R
+import ca.allanwang.kau.adapters.FastItemThemedAdapter
+import ca.allanwang.kau.adapters.ThemableIItemColors
+import ca.allanwang.kau.adapters.ThemableIItemColorsDelegate
+import ca.allanwang.kau.animators.FadeScaleAnimator
+import ca.allanwang.kau.iitems.CardIItem
import ca.allanwang.kau.iitems.CutoutIItem
+import ca.allanwang.kau.iitems.HeaderIItem
import ca.allanwang.kau.iitems.LibraryIItem
import ca.allanwang.kau.utils.*
import ca.allanwang.kau.widgets.ElasticDragDismissFrameLayout
@@ -19,7 +25,6 @@ import ca.allanwang.kau.widgets.InkPageIndicator
import com.mikepenz.aboutlibraries.Libs
import com.mikepenz.aboutlibraries.entity.Library
import com.mikepenz.fastadapter.IItem
-import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread
import java.security.InvalidParameterException
@@ -34,19 +39,52 @@ import java.security.InvalidParameterException
* Note that for the auto detection to work, the R fields must be excluded from Proguard
* Manual lib listings and other extra modifications can be done so by overriding the open functions
*/
-abstract class AboutActivityBase(val rClass: Class<*>, val configBuilder: Configs.() -> Unit = {}) : AppCompatActivity() {
+abstract class AboutActivityBase(val rClass: Class<*>, val configBuilder: Configs.() -> Unit = {}) : AppCompatActivity(), ViewPager.OnPageChangeListener {
val draggableFrame: ElasticDragDismissFrameLayout by bindView(R.id.about_draggable_frame)
val pager: ViewPager by bindView(R.id.about_pager)
val indicator: InkPageIndicator by bindView(R.id.about_indicator)
+ /**
+ * Holds some common configurations that may be added directly from the constructor
+ * Applied lazily since it needs the context to fetch resources
+ */
val configs: Configs by lazy { Configs().apply { configBuilder() } }
+ /**
+ * Number of pages in the adapter
+ * Defaults to just the main view and lib view
+ */
+ open val pageCount: Int = 2
+ /**
+ * Page position for the libs
+ * This is generated automatically if [inflateLibPage] is called
+ */
+ private var libPage: Int = -2
+ /**
+ * Holds that status of each page
+ * 0 means nothing has happened
+ * 1 means this page has been in view at least once
+ * The rest is up to you
+ */
+ lateinit var pageStatus: IntArray
+ /**
+ * Holds the lib items once they are fetched asynchronously
+ */
+ var libItems: List<LibraryIItem>? = null
+ /**
+ * Holds the adapter for the library page; this is generated later because it uses the config colors
+ */
+ lateinit var libAdapter: FastItemThemedAdapter<IItem<*, *>>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.kau_activity_about)
+ pageStatus = IntArray(pageCount)
+ libAdapter = FastItemThemedAdapter(configs)
+ if (configs.textColor != null) indicator.setColour(configs.textColor!!)
with(pager) {
adapter = AboutPagerAdapter()
pageMargin = dimenPixelSize(R.dimen.kau_spacing_normal)
+ addOnPageChangeListener(this@AboutActivityBase)
}
indicator.setViewPager(pager)
draggableFrame.addListener(object : ElasticDragDismissFrameLayout.SystemChromeFader(this) {
@@ -62,22 +100,26 @@ abstract class AboutActivityBase(val rClass: Class<*>, val configBuilder: Config
})
}
- inner class Configs {
+ inner class Configs : ThemableIItemColors by ThemableIItemColorsDelegate() {
var cutoutTextRes: Int = -1
var cutoutText: String? = null
var cutoutDrawableRes: Int = -1
var cutoutDrawable: Drawable? = null
- var mainPageTitleRes: Int = -1
- var mainPageTitle: String = "Kau test"
+ var cutoutForeground: Int? = null
var libPageTitleRes: Int = -1
var libPageTitle: String? = string(R.string.kau_about_libraries_intro)
+ /**
+ * Transition to be called if the view is dragged down
+ */
var transitionExitReversed: Int = R.transition.kau_about_return_downward
}
+ /**
+ * Method to fetch the library list
+ * This is fetched asynchronously and you may override it to customize the list
+ */
open fun getLibraries(libs: Libs): List<Library> = libs.prepareLibraries(this, null, null, true, true)
- open val pageCount: Int = 2
-
/**
* Gets the view associated with the given page position
* Keep in mind that when inflating, do NOT add the view to the viewgroup
@@ -85,39 +127,50 @@ abstract class AboutActivityBase(val rClass: Class<*>, val configBuilder: Config
*/
open fun getPage(position: Int, layoutInflater: LayoutInflater, parent: ViewGroup): View {
return when (position) {
- 0 -> inflateMainPage(layoutInflater, parent)
- pageCount - 1 -> inflateLibPage(layoutInflater, parent)
+ 0 -> inflateMainPage(layoutInflater, parent, position)
+ pageCount - 1 -> inflateLibPage(layoutInflater, parent, position)
else -> throw InvalidParameterException()
}
}
- open fun inflateMainPage(layoutInflater: LayoutInflater, parent: ViewGroup): View {
- val fastAdapter = FastItemAdapter<IItem<*, *>>()
- val recycler = fullLinearRecycler {
- adapter = fastAdapter
- }
+ /**
+ * Create the main view with the cutout
+ */
+ open fun inflateMainPage(layoutInflater: LayoutInflater, parent: ViewGroup, position: Int): View {
+ val fastAdapter = FastItemThemedAdapter<IItem<*, *>>(configs)
+ val recycler = fullLinearRecycler { adapter = fastAdapter }
fastAdapter.add(CutoutIItem {
with(configs) {
text = string(cutoutTextRes, cutoutText)
drawable = drawable(cutoutDrawableRes, cutoutDrawable)
+ if (configs.cutoutForeground != null) foregroundColor = configs.cutoutForeground!!
}
+ }.apply {
+ themeEnabled = configs.cutoutForeground == null
})
+ postInflateMainPage(fastAdapter)
return recycler
}
+ open fun postInflateMainPage(adapter: FastItemThemedAdapter<IItem<*, *>>) {
+
+ }
- open fun inflateLibPage(layoutInflater: LayoutInflater, parent: ViewGroup): View {
+ /**
+ * Create the lib view with the list of libraries
+ */
+ open fun inflateLibPage(layoutInflater: LayoutInflater, parent: ViewGroup, position: Int): View {
+ libPage = position
val v = layoutInflater.inflate(R.layout.kau_recycler_detached_background, parent, false)
- val fastAdapter = FastItemAdapter<IItem<*, *>>()
val recycler = v.findViewById<RecyclerView>(R.id.kau_recycler_detached)
- recycler.adapter = fastAdapter
+ recycler.adapter = libAdapter
+ recycler.itemAnimator = FadeScaleAnimator(itemDelayFactor = 0.2f).apply { addDuration = 300; interpolator = AnimHolder.decelerateInterpolator(this@AboutActivityBase) }
val background = v.findViewById<View>(R.id.kau_recycler_detached_background)
+ if (configs.backgroundColor != null) background.setBackgroundColor(configs.backgroundColor!!.colorToForeground())
doAsync {
- val libs = getLibraries(Libs(this@AboutActivityBase, Libs.toStringArray(rClass.fields))).map { LibraryIItem(it) }
- uiThread {
- recycler.transitionDelayed(R.transition.kau_enter_slide_top) //TODO fix this
- fastAdapter.add(libs)
- }
+ libItems = getLibraries(Libs(this@AboutActivityBase, Libs.toStringArray(rClass.fields))).map { LibraryIItem(it) }
+ if (libPage >= 0 && pageStatus[libPage] == 1)
+ uiThread { addLibItems() }
}
return v
}
@@ -142,9 +195,34 @@ abstract class AboutActivityBase(val rClass: Class<*>, val configBuilder: Config
override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object`
+ /**
+ * Only get page if view does not exist
+ */
private fun getPage(position: Int, parent: ViewGroup): View {
if (views[position] == null) views[position] = getPage(position, layoutInflater, parent)
return views[position]!!
}
}
+
+ override fun onPageScrollStateChanged(state: Int) {}
+
+ override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
+
+ override fun onPageSelected(position: Int) {
+ if (pageStatus[position] == 0) pageStatus[position] = 1 // mark as seen if previously null
+ if (position == libPage && libItems != null && pageStatus[position] == 1) {
+ pageStatus[position] = 2 //add libs and mark as such
+ postDelayed(300) { addLibItems() } //delay so that the animations occur once the page is fully switched
+ }
+ }
+
+ internal fun addLibItems() {
+ libAdapter.add(HeaderIItem(text = configs.libPageTitle, textRes = configs.libPageTitleRes))
+ .add(libItems)
+ }
+
+ override fun onDestroy() {
+ AnimHolder.decelerateInterpolator.invalidate() //clear the reference to the interpolators we've used
+ super.onDestroy()
+ }
} \ No newline at end of file
diff --git a/library/src/main/kotlin/ca/allanwang/kau/adapters/FastItemThemedAdapter.kt b/library/src/main/kotlin/ca/allanwang/kau/adapters/FastItemThemedAdapter.kt
new file mode 100644
index 0000000..f7a0ecb
--- /dev/null
+++ b/library/src/main/kotlin/ca/allanwang/kau/adapters/FastItemThemedAdapter.kt
@@ -0,0 +1,179 @@
+package ca.allanwang.kau.adapters
+
+import android.view.View
+import android.widget.ImageView
+import android.widget.TextView
+import ca.allanwang.kau.utils.adjustAlpha
+import com.mikepenz.fastadapter.IExpandable
+import com.mikepenz.fastadapter.IItem
+import com.mikepenz.fastadapter.ISubItem
+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: MutableList<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: MutableList<Item>): FastItemAdapter<Item> {
+ injectTheme(items)
+ injectTheme(items)
+ return super.add(items)
+ }
+
+ override fun set(items: MutableList<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: MutableList<Item>?, retainFilter: Boolean): FastItemAdapter<Item> {
+ injectTheme(items)
+ return super.setNewList(items, retainFilter)
+ }
+
+ override fun setNewList(items: MutableList<Item>?): FastItemAdapter<Item> {
+ injectTheme(items)
+ return super.setNewList(items)
+ }
+
+ override fun <T, S> setSubItems(collapsible: T, subItems: MutableList<S>?): T where S : IItem<*, *>?, T : IItem<*, *>?, T : IExpandable<T, S>?, S : ISubItem<Item, T>? {
+ injectTheme(subItems)
+ return super.setSubItems(collapsible, subItems)
+ }
+
+ internal fun injectTheme(items: Collection<IItem<*, *>?>?) {
+ items?.forEach { injectTheme(it) }
+ }
+
+ internal 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 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) }
+ }
+
+ override fun bindIconColor(vararg views: ImageView) {
+ val color = accentColor ?: textColor ?: return
+ views.forEach { it.drawable.setTint(color) }
+ }
+} \ No newline at end of file
diff --git a/library/src/main/kotlin/ca/allanwang/kau/animators/BaseDelayAnimator.kt b/library/src/main/kotlin/ca/allanwang/kau/animators/BaseDelayAnimator.kt
new file mode 100644
index 0000000..c649376
--- /dev/null
+++ b/library/src/main/kotlin/ca/allanwang/kau/animators/BaseDelayAnimator.kt
@@ -0,0 +1,45 @@
+package ca.allanwang.kau.animators
+
+import android.support.v7.widget.RecyclerView
+import android.view.ViewPropertyAnimator
+
+/**
+ * Created by Allan Wang on 2017-06-27.
+ *
+ * Base for delayed animators
+ * item delay factor by default can be 0.125f
+ */
+abstract class BaseDelayAnimator(val itemDelayFactor: Float) : DefaultAnimator() {
+
+ override abstract fun addAnimationPrepare(holder: RecyclerView.ViewHolder)
+
+ override fun addAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator {
+ return holder.itemView.animate().apply {
+ startDelay = Math.max(0L, (holder.adapterPosition * addDuration * itemDelayFactor).toLong())
+ duration = this@BaseDelayAnimator.addDuration
+ interpolator = this@BaseDelayAnimator.interpolator
+ }
+ }
+
+
+ override abstract fun addAnimationCleanup(holder: RecyclerView.ViewHolder)
+
+ override fun getAddDelay(remove: Long, move: Long, change: Long): Long = 0
+
+ override fun getRemoveDelay(remove: Long, move: Long, change: Long): Long = 0
+
+ /**
+ * Partial removal animation
+ * As of now, all it does it change the alpha
+ * To have it slide, add onto it in a sub class
+ */
+ override fun removeAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator {
+ return holder.itemView.animate().apply {
+ duration = this@BaseDelayAnimator.removeDuration
+ startDelay = Math.max(0L, (holder.adapterPosition * removeDuration * itemDelayFactor).toLong())
+ interpolator = this@BaseDelayAnimator.interpolator
+ }
+ }
+
+ override abstract fun removeAnimationCleanup(holder: RecyclerView.ViewHolder)
+} \ No newline at end of file
diff --git a/library/src/main/kotlin/ca/allanwang/kau/animators/BaseItemAnimator.java b/library/src/main/kotlin/ca/allanwang/kau/animators/BaseItemAnimator.java
index f25678f..69c2cf3 100644
--- a/library/src/main/kotlin/ca/allanwang/kau/animators/BaseItemAnimator.java
+++ b/library/src/main/kotlin/ca/allanwang/kau/animators/BaseItemAnimator.java
@@ -63,7 +63,7 @@ public abstract class BaseItemAnimator extends SimpleItemAnimator {
ArrayList<ViewHolder> mRemoveAnimations = new ArrayList<>();
ArrayList<ViewHolder> mChangeAnimations = new ArrayList<>();
- Interpolator interpolator;
+ public Interpolator interpolator;
private static class MoveInfo {
public ViewHolder holder;
diff --git a/library/src/main/kotlin/ca/allanwang/kau/animators/BaseSlideAlphaAnimator.kt b/library/src/main/kotlin/ca/allanwang/kau/animators/BaseSlideAlphaAnimator.kt
new file mode 100644
index 0000000..a963358
--- /dev/null
+++ b/library/src/main/kotlin/ca/allanwang/kau/animators/BaseSlideAlphaAnimator.kt
@@ -0,0 +1,52 @@
+package ca.allanwang.kau.animators
+
+import android.support.v7.widget.RecyclerView
+import android.view.ViewPropertyAnimator
+
+/**
+ * Created by Allan Wang on 2017-06-27.
+ *
+ * Base for sliding animators
+ * item delay factor by default can be 0.125f
+ */
+abstract class BaseSlideAlphaAnimator(itemDelayFactor: Float) : BaseDelayAnimator(itemDelayFactor) {
+
+ override fun addAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator {
+ return super.addAnimation(holder).apply {
+ translationY(0f)
+ translationX(0f)
+ alpha(1f)
+ }
+ }
+
+ final override fun addAnimationCleanup(holder: RecyclerView.ViewHolder) {
+ with(holder.itemView) {
+ translationY = 0f
+ translationX = 0f
+ alpha = 1f
+ }
+ }
+
+ override fun getAddDelay(remove: Long, move: Long, change: Long): Long = 0
+
+ override fun getRemoveDelay(remove: Long, move: Long, change: Long): Long = 0
+
+ /**
+ * Partial removal animation
+ * As of now, all it does it change the alpha
+ * To have it slide, add onto it in a sub class
+ */
+ override fun removeAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator {
+ return super.addAnimation(holder).apply {
+ alpha(0f)
+ }
+ }
+
+ override final fun removeAnimationCleanup(holder: RecyclerView.ViewHolder) {
+ with(holder.itemView) {
+ translationY = 0f
+ translationX = 0f
+ alpha = 1f
+ }
+ }
+} \ No newline at end of file
diff --git a/library/src/main/kotlin/ca/allanwang/kau/animators/DefaultAnimator.kt b/library/src/main/kotlin/ca/allanwang/kau/animators/DefaultAnimator.kt
index abb22c8..9aeafde 100644
--- a/library/src/main/kotlin/ca/allanwang/kau/animators/DefaultAnimator.kt
+++ b/library/src/main/kotlin/ca/allanwang/kau/animators/DefaultAnimator.kt
@@ -7,6 +7,7 @@ import android.view.ViewPropertyAnimator
* 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)
diff --git a/library/src/main/kotlin/ca/allanwang/kau/animators/FadeScaleAnimator.kt b/library/src/main/kotlin/ca/allanwang/kau/animators/FadeScaleAnimator.kt
new file mode 100644
index 0000000..e968cda
--- /dev/null
+++ b/library/src/main/kotlin/ca/allanwang/kau/animators/FadeScaleAnimator.kt
@@ -0,0 +1,51 @@
+package ca.allanwang.kau.animators
+
+import android.support.v7.widget.RecyclerView
+import android.view.ViewPropertyAnimator
+
+/**
+ * Created by Allan Wang on 2017-06-29.
+ */
+open class FadeScaleAnimator(val scaleFactor: Float = 0.7f, itemDelayFactor: Float = 0.125f) : BaseDelayAnimator(itemDelayFactor) {
+
+ override fun addAnimationPrepare(holder: RecyclerView.ViewHolder) {
+ with(holder.itemView) {
+ scaleX = scaleFactor
+ scaleY = scaleFactor
+ alpha = 0f
+ }
+ }
+
+ override final fun addAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator {
+ return super.addAnimation(holder).apply {
+ scaleX(1f)
+ scaleY(1f)
+ alpha(1f)
+ }
+ }
+
+
+ final override fun addAnimationCleanup(holder: RecyclerView.ViewHolder) {
+ with(holder.itemView) {
+ scaleX = 1f
+ scaleY = 1f
+ alpha = 1f
+ }
+ }
+
+ override fun removeAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator {
+ return super.removeAnimation(holder).apply {
+ scaleX(scaleFactor)
+ scaleY(scaleFactor)
+ alpha(0f)
+ }
+ }
+
+ override final fun removeAnimationCleanup(holder: RecyclerView.ViewHolder) {
+ with(holder.itemView) {
+ translationY = 0f
+ translationX = 0f
+ alpha = 1f
+ }
+ }
+} \ No newline at end of file
diff --git a/library/src/main/kotlin/ca/allanwang/kau/animators/SlideUpAlphaAnimator.kt b/library/src/main/kotlin/ca/allanwang/kau/animators/SlideUpAlphaAnimator.kt
deleted file mode 100644
index 3b1b223..0000000
--- a/library/src/main/kotlin/ca/allanwang/kau/animators/SlideUpAlphaAnimator.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-package ca.allanwang.kau.animators
-
-import android.support.v7.widget.RecyclerView
-import android.view.ViewPropertyAnimator
-
-/**
- * Created by Allan Wang on 2017-06-27.
- */
-class SlideUpAlphaAnimator : DefaultAnimator() {
- override fun addAnimationPrepare(holder: RecyclerView.ViewHolder) {
- with(holder.itemView) {
- translationY = height.toFloat()
- alpha = 0f
- }
- }
-
- override fun addAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator {
- return holder.itemView.animate().apply {
- translationY(0f)
- alpha(0f)
- duration = this@SlideUpAlphaAnimator.addDuration
- interpolator = this@SlideUpAlphaAnimator.interpolator
- }
- }
-
- public override fun addAnimationCleanup(holder: RecyclerView.ViewHolder) {
- with(holder.itemView) {
- translationY = 0f
- alpha = 1f
- }
- }
-
- override fun getAddDelay(remove: Long, move: Long, change: Long): Long = 0
-
- override fun getRemoveDelay(remove: Long, move: Long, change: Long): Long = 0
-
- override fun removeAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator {
- return holder.itemView.animate().apply {
- duration = this@SlideUpAlphaAnimator.removeDuration
- alpha(0f)
- translationY(holder.itemView.height.toFloat())
- interpolator = this@SlideUpAlphaAnimator.interpolator
- }
- }
-
- override fun removeAnimationCleanup(holder: RecyclerView.ViewHolder) {
- with(holder.itemView) {
- translationY = 0f
- alpha = 1f
- }
- }
-} \ No newline at end of file
diff --git a/library/src/main/kotlin/ca/allanwang/kau/animators/SlideUpExitRightAnimator.kt b/library/src/main/kotlin/ca/allanwang/kau/animators/SlideUpExitRightAnimator.kt
new file mode 100644
index 0000000..8670493
--- /dev/null
+++ b/library/src/main/kotlin/ca/allanwang/kau/animators/SlideUpExitRightAnimator.kt
@@ -0,0 +1,23 @@
+package ca.allanwang.kau.animators
+
+import android.support.v7.widget.RecyclerView
+import android.view.ViewPropertyAnimator
+
+/**
+ * Created by Allan Wang on 2017-06-27.
+ */
+class SlideUpExitRightAnimator(itemDelayFactor: Float = 0.125f) : BaseSlideAlphaAnimator(itemDelayFactor) {
+
+ override fun addAnimationPrepare(holder: RecyclerView.ViewHolder) {
+ with(holder.itemView) {
+ translationY = height.toFloat()
+ alpha = 0f
+ }
+ }
+
+ override fun removeAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator {
+ return super.removeAnimation(holder).apply {
+ translationX(holder.itemView.width.toFloat())
+ }
+ }
+} \ No newline at end of file
diff --git a/library/src/main/kotlin/ca/allanwang/kau/changelog/Changelog.kt b/library/src/main/kotlin/ca/allanwang/kau/changelog/Changelog.kt
index a91d0af..74e933c 100644
--- a/library/src/main/kotlin/ca/allanwang/kau/changelog/Changelog.kt
+++ b/library/src/main/kotlin/ca/allanwang/kau/changelog/Changelog.kt
@@ -14,7 +14,11 @@ import android.widget.TextView
import ca.allanwang.kau.R
import ca.allanwang.kau.utils.bindOptionalView
import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.materialDialog
+import ca.allanwang.kau.utils.use
import com.afollestad.materialdialogs.MaterialDialog
+import org.jetbrains.anko.doAsync
+import org.jetbrains.anko.uiThread
import org.xmlpull.v1.XmlPullParser
import java.util.*
@@ -24,20 +28,17 @@ import java.util.*
*/
fun Context.showChangelog(@XmlRes xmlRes: Int, @ColorInt textColor: Int? = null, customize: MaterialDialog.Builder.() -> Unit = {}) {
- val mHandler = Handler()
- Thread(Runnable {
- val items = parse(this, xmlRes)
- mHandler.post(object : TimerTask() {
- override fun run() {
- val builder = MaterialDialog.Builder(this@showChangelog)
- .title(R.string.kau_changelog)
- .positiveText(R.string.kau_great)
- .adapter(ChangelogAdapter(items, textColor), null)
- builder.customize()
- builder.show()
+ doAsync {
+ val items = parse(this@showChangelog, xmlRes)
+ uiThread {
+ materialDialog {
+ title(R.string.kau_changelog)
+ positiveText(R.string.kau_great)
+ adapter(ChangelogAdapter(items, textColor), null)
+ customize()
}
- })
- }).start()
+ }
+ }
}
/**
@@ -72,7 +73,7 @@ internal class ChangelogAdapter(val items: List<Pair<String, ChangelogType>>, @C
internal fun parse(context: Context, @XmlRes xmlRes: Int): List<Pair<String, ChangelogType>> {
val items = mutableListOf<Pair<String, ChangelogType>>()
context.resources.getXml(xmlRes).use {
- parser ->
+ parser: XmlResourceParser ->
var eventType = parser.eventType
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG)
diff --git a/library/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt b/library/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt
index 36e7ef8..c690468 100644
--- a/library/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt
+++ b/library/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt
@@ -10,6 +10,8 @@ import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import ca.allanwang.kau.R
+import ca.allanwang.kau.adapters.ThemableIItem
+import ca.allanwang.kau.adapters.ThemableIItemDelegate
import ca.allanwang.kau.utils.*
import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.items.AbstractItem
@@ -22,8 +24,8 @@ import com.mikepenz.iconics.typeface.IIcon
* 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 = {}) : AbstractItem<CardIItem, CardIItem.ViewHolder>() {
-
+class CardIItem(val builder: Config.() -> Unit = {}
+) : AbstractItem<CardIItem, CardIItem.ViewHolder>(), ThemableIItem by ThemableIItemDelegate() {
companion object {
fun bindClickEvents(fastAdapter: FastAdapter<CardIItem>) {
@@ -87,6 +89,13 @@ class CardIItem(val builder: Config.() -> Unit = {}) : AbstractItem<CardIItem, C
)
holder.card.setOnClickListener(cardClick)
}
+ with(holder) {
+ bindTextColor(title)
+ bindTextColorSecondary(description)
+ bindAccentColor(button)
+ if (configs.imageIIcon != null) bindIconColor(icon)
+ bindBackgroundColor(card)
+ }
}
}
diff --git a/library/src/main/kotlin/ca/allanwang/kau/iitems/CutoutIItem.kt b/library/src/main/kotlin/ca/allanwang/kau/iitems/CutoutIItem.kt
index d138917..627e1df 100644
--- a/library/src/main/kotlin/ca/allanwang/kau/iitems/CutoutIItem.kt
+++ b/library/src/main/kotlin/ca/allanwang/kau/iitems/CutoutIItem.kt
@@ -3,6 +3,8 @@ package ca.allanwang.kau.iitems
import android.support.v7.widget.RecyclerView
import android.view.View
import ca.allanwang.kau.R
+import ca.allanwang.kau.adapters.ThemableIItem
+import ca.allanwang.kau.adapters.ThemableIItemDelegate
import ca.allanwang.kau.utils.bindView
import ca.allanwang.kau.views.CutoutView
import com.mikepenz.fastadapter.items.AbstractItem
@@ -12,7 +14,8 @@ import com.mikepenz.fastadapter.items.AbstractItem
*
* Just a cutout item with some defaults in [R.layout.kau_iitem_cutout]
*/
-class CutoutIItem(val config: CutoutView.() -> Unit = {}) : AbstractItem<CutoutIItem, CutoutIItem.ViewHolder>() {
+class CutoutIItem(val config: CutoutView.() -> Unit = {}
+) : AbstractItem<CutoutIItem, CutoutIItem.ViewHolder>(), ThemableIItem by ThemableIItemDelegate() {
override fun getType(): Int = R.id.kau_item_cutout
@@ -23,6 +26,7 @@ class CutoutIItem(val config: CutoutView.() -> Unit = {}) : AbstractItem<CutoutI
override fun bindView(holder: ViewHolder, payloads: MutableList<Any>?) {
super.bindView(holder, payloads)
with(holder) {
+ if (accentColor != null && themeEnabled) cutout.foregroundColor = accentColor!!
cutout.config()
}
}
diff --git a/library/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt b/library/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt
new file mode 100644
index 0000000..e994781
--- /dev/null
+++ b/library/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt
@@ -0,0 +1,49 @@
+package ca.allanwang.kau.iitems
+
+import android.support.v7.widget.CardView
+import android.support.v7.widget.RecyclerView
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import ca.allanwang.kau.R
+import ca.allanwang.kau.adapters.ThemableIItem
+import ca.allanwang.kau.adapters.ThemableIItemDelegate
+import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.string
+import com.mikepenz.fastadapter.items.AbstractItem
+
+/**
+ * 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 = -1
+) : AbstractItem<HeaderIItem, HeaderIItem.ViewHolder>(), ThemableIItem by ThemableIItemDelegate() {
+
+ var text: String = text ?: "Header Placeholder"
+
+ override fun getType(): Int = R.id.kau_item_header_big_margin_top
+
+ override fun getLayoutRes(): Int = R.layout.kau_iitem_header
+
+ 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
+ }
+
+ override fun getViewHolder(v: View): ViewHolder = ViewHolder(v)
+
+ class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
+ val text: TextView by bindView(R.id.kau_header_text)
+ val container: CardView by bindView(R.id.kau_header_container)
+ }
+
+} \ No newline at end of file
diff --git a/library/src/main/kotlin/ca/allanwang/kau/iitems/LibraryIItem.kt b/library/src/main/kotlin/ca/allanwang/kau/iitems/LibraryIItem.kt
index e617aaa..0b1b7cb 100644
--- a/library/src/main/kotlin/ca/allanwang/kau/iitems/LibraryIItem.kt
+++ b/library/src/main/kotlin/ca/allanwang/kau/iitems/LibraryIItem.kt
@@ -1,32 +1,29 @@
package ca.allanwang.kau.iitems
-/**
- * Created by Allan Wang on 2017-06-27.
- */
-
import android.os.Build
import android.support.v7.widget.CardView
import android.support.v7.widget.RecyclerView
import android.text.Html
import android.view.View
-import android.widget.LinearLayout
import android.widget.TextView
import ca.allanwang.kau.R
+import ca.allanwang.kau.adapters.ThemableIItem
+import ca.allanwang.kau.adapters.ThemableIItemDelegate
import ca.allanwang.kau.utils.bindView
import ca.allanwang.kau.utils.gone
import ca.allanwang.kau.utils.visible
import com.mikepenz.aboutlibraries.entity.Library
import com.mikepenz.fastadapter.items.AbstractItem
-
/**
- * Created by mikepenz on 28.12.15.
+ * Created by Allan Wang on 2017-06-27.
*/
-class LibraryIItem(val lib: Library) : AbstractItem<LibraryIItem, LibraryIItem.ViewHolder>() {
+class LibraryIItem(val lib: Library
+) : AbstractItem<LibraryIItem, LibraryIItem.ViewHolder>(), ThemableIItem by ThemableIItemDelegate() {
- override fun getType(): Int = R.id.kau_item_about_library
+ override fun getType(): Int = R.id.kau_item_library
- override fun getLayoutRes(): Int = R.layout.kau_about_iitem_library
+ override fun getLayoutRes(): Int = R.layout.kau_iitem_library
override fun isSelectable(): Boolean = false
@@ -40,26 +37,31 @@ class LibraryIItem(val lib: Library) : AbstractItem<LibraryIItem, LibraryIItem.V
Html.fromHtml(lib.libraryDescription, Html.FROM_HTML_MODE_LEGACY)
else Html.fromHtml(lib.libraryDescription)
bottomDivider.gone()
- bottomContainer.gone()
if (lib.libraryVersion?.isNotBlank() ?: false) {
bottomDivider.visible()
- bottomContainer.visible()
- version.text = lib.libraryVersion
+ version.visible().text = lib.libraryVersion
}
if (lib.license?.licenseName?.isNotBlank() ?: false) {
bottomDivider.visible()
- bottomContainer.visible()
- license.text = lib.license?.licenseName
+ license.visible().text = lib.license?.licenseName
}
+ bindTextColor(name, creator)
+ bindTextColorSecondary(description)
+ bindAccentColor(license, version)
+ bindDividerColor(divider, bottomDivider)
+ bindBackgroundColor(card)
}
}
override fun unbindView(holder: ViewHolder) {
super.unbindView(holder)
- with (holder) {
+ with(holder) {
name.text = null
creator.text = null
description.text = null
+ bottomDivider.gone()
+ version.gone().text = null
+ license.gone().text = null
}
}
@@ -72,8 +74,6 @@ class LibraryIItem(val lib: Library) : AbstractItem<LibraryIItem, LibraryIItem.V
val description: TextView by bindView(R.id.lib_item_description)
val version: TextView by bindView(R.id.lib_item_version)
val license: TextView by bindView(R.id.lib_item_license)
- val bottomContainer: LinearLayout by bindView(R.id.lib_item_bottom_container)
-
val divider: View by bindView(R.id.lib_item_top_divider)
val bottomDivider: View by bindView(R.id.lib_item_bottom_divider)
}
diff --git a/library/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt b/library/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt
index 3739dec..3db8b9c 100644
--- a/library/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt
+++ b/library/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt
@@ -1,7 +1,5 @@
package ca.allanwang.kau.utils
-import android.view.animation.AnimationUtils
-import ca.allanwang.kau.kotlin.lazyContext
import ca.allanwang.kau.kotlin.lazyInterpolator
/**
@@ -12,5 +10,6 @@ import ca.allanwang.kau.kotlin.lazyInterpolator
object AnimHolder {
val fastOutSlowInInterpolator = lazyInterpolator(android.R.interpolator.fast_out_linear_in)
+ val decelerateInterpolator = lazyInterpolator(android.R.interpolator.decelerate_cubic)
} \ No newline at end of file
diff --git a/library/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt b/library/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt
index 55fb9ea..aa0736e 100644
--- a/library/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt
+++ b/library/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt
@@ -6,6 +6,7 @@ import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
+import android.os.Handler
import android.os.Looper
import android.support.annotation.IntRange
import ca.allanwang.kau.R
@@ -79,4 +80,30 @@ annotation class KauUtils
setBounds(0, 0, canvas.width, canvas.height)
draw(canvas)
return bitmap
+}
+
+/**
+ * Use block for autocloseables
+ */
+inline fun <T : AutoCloseable, R> T.use(block: (T) -> R): R {
+ var closed = false
+ try {
+ return block(this)
+ } catch (e: Exception) {
+ closed = true
+ try {
+ close()
+ } catch (closeException: Exception) {
+ e.addSuppressed(closeException)
+ }
+ throw e
+ } finally {
+ if (!closed) {
+ close()
+ }
+ }
+}
+
+fun postDelayed(delay: Long, action: () -> Unit) {
+ Handler().postDelayed(action, delay)
} \ No newline at end of file
diff --git a/library/src/main/kotlin/ca/allanwang/kau/widgets/ElasticDragDismissFrameLayout.kt b/library/src/main/kotlin/ca/allanwang/kau/widgets/ElasticDragDismissFrameLayout.kt
index a9e9ee2..38c99c3 100644
--- a/library/src/main/kotlin/ca/allanwang/kau/widgets/ElasticDragDismissFrameLayout.kt
+++ b/library/src/main/kotlin/ca/allanwang/kau/widgets/ElasticDragDismissFrameLayout.kt
@@ -23,7 +23,6 @@ import android.util.AttributeSet
import android.view.View
import android.widget.FrameLayout
import ca.allanwang.kau.R
-import ca.allanwang.kau.logging.KL
import ca.allanwang.kau.utils.*
/**
@@ -94,11 +93,9 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor(
override fun onNestedPreScroll(target: View, dx: Int, dy: Int, consumed: IntArray) {
// if we're in a drag gesture and the user reverses up the we should take those events
- KL.e("Pre $dy ${consumed[1]}")
if (draggingDown && dy > 0 || draggingUp && dy < 0) {
dragScale(dy)
consumed[1] = dy
- KL.e("Pre consumed")
}
}
@@ -145,7 +142,6 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor(
if (scroll == 0) return
totalDrag += scroll.toFloat()
-// KL.e("Drag $scroll $totalDrag")
// track the direction & set the pivot point for scaling
// don't double track i.e. if start dragging down and then reverse, keep tracking as
diff --git a/library/src/main/kotlin/ca/allanwang/kau/widgets/InkPageIndicator.java b/library/src/main/kotlin/ca/allanwang/kau/widgets/InkPageIndicator.java
index b6ec0d0..78e915d 100644
--- a/library/src/main/kotlin/ca/allanwang/kau/widgets/InkPageIndicator.java
+++ b/library/src/main/kotlin/ca/allanwang/kau/widgets/InkPageIndicator.java
@@ -27,6 +27,7 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
+import android.support.annotation.ColorInt;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
@@ -37,6 +38,7 @@ import java.util.Arrays;
import ca.allanwang.kau.R;
import ca.allanwang.kau.utils.AnimHolder;
+import ca.allanwang.kau.utils.ColorUtilsKt;
/**
* An ink inspired widget for indicating pages in a {@link ViewPager}.
@@ -62,6 +64,13 @@ public class InkPageIndicator extends View implements ViewPager.OnPageChangeList
private int unselectedColour;
private int selectedColour;
+ public void setColour(@ColorInt int color) {
+ selectedColour = color;
+ unselectedColour = ColorUtilsKt.adjustAlpha(color, 0.5f);
+ selectedPaint.setColor(selectedColour);
+ unselectedPaint.setColor(unselectedColour);
+ }
+
// derived from attributes
private float dotRadius;
private float halfDotRadius;