diff options
author | Allan Wang <me@allanwang.ca> | 2017-06-29 16:16:15 -0700 |
---|---|---|
committer | Allan Wang <me@allanwang.ca> | 2017-06-29 16:16:15 -0700 |
commit | bfb16f2d56dd4da8d302a924efb7ea119582fde0 (patch) | |
tree | 2fd6ae1f5ffe305ce761ad88609692c163e6ebb3 /library/src/main/kotlin | |
parent | 8f2e56eb5ecfc6b5ce2f1530ead6fe73f5bfe89c (diff) | |
download | kau-bfb16f2d56dd4da8d302a924efb7ea119582fde0.tar.gz kau-bfb16f2d56dd4da8d302a924efb7ea119582fde0.tar.bz2 kau-bfb16f2d56dd4da8d302a924efb7ea119582fde0.zip |
Finalize about activity
Diffstat (limited to 'library/src/main/kotlin')
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; |