diff options
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/intro')
3 files changed, 298 insertions, 0 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt new file mode 100644 index 00000000..d1d64712 --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt @@ -0,0 +1,51 @@ +package com.pitchedapps.frost.intro + +import android.os.Bundle +import android.view.View +import ca.allanwang.kau.utils.bindViewResettable +import ca.allanwang.kau.utils.scaleXY +import com.pitchedapps.frost.R +import com.pitchedapps.frost.activities.IntroActivity +import com.pitchedapps.frost.utils.Prefs +import com.pitchedapps.frost.utils.Theme + +/** + * Created by Allan Wang on 2017-07-28. + */ +class IntroFragmentTheme : BaseIntroFragment(R.layout.intro_theme) { + + val light: View by bindViewResettable(R.id.intro_theme_light) + val dark: View by bindViewResettable(R.id.intro_theme_dark) + val amoled: View by bindViewResettable(R.id.intro_theme_amoled) + val glass: View by bindViewResettable(R.id.intro_theme_glass) + + val themeList + get() = listOf(light, dark, amoled, glass) + + override fun viewArray(): Array<Array<out View>> + = arrayOf(arrayOf(title), arrayOf(light, dark), arrayOf(amoled, glass)) + + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + light.setThemeClick(Theme.LIGHT) + dark.setThemeClick(Theme.DARK) + amoled.setThemeClick(Theme.AMOLED) + glass.setThemeClick(Theme.GLASS) + val currentTheme = Prefs.theme - 1 + if (currentTheme in 0..3) + themeList.forEachIndexed { index, v -> v.scaleXY = if (index == currentTheme) 1.6f else 0.8f } + } + + private fun View.setThemeClick(theme: Theme) { + setOnClickListener { + v -> + Prefs.theme = theme.ordinal + (activity as IntroActivity).apply { + ripple.ripple(Prefs.bgColor, v.x + v.pivotX, v.y + v.pivotY) + theme() + } + themeList.forEach { it.animate().scaleXY(if (it == this) 1.6f else 0.8f).start() } + } + } + +}
\ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt new file mode 100644 index 00000000..d19a488d --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt @@ -0,0 +1,112 @@ +package com.pitchedapps.frost.intro + +import android.graphics.drawable.Drawable +import android.graphics.drawable.LayerDrawable +import android.os.Bundle +import android.view.View +import ca.allanwang.kau.utils.colorToForeground +import ca.allanwang.kau.utils.tint +import ca.allanwang.kau.utils.withAlpha +import com.pitchedapps.frost.R +import com.pitchedapps.frost.utils.Prefs + +/** + * Created by Allan Wang on 2017-07-28. + */ +abstract class BaseImageIntroFragment(val titleRes: Int, val imageRes: Int, val descRes: Int) : BaseIntroFragment(R.layout.intro_image) { + + val imageDrawable: LayerDrawable by lazyResettableRegistered { image.drawable as LayerDrawable } + val phone: Drawable by lazyResettableRegistered { imageDrawable.findDrawableByLayerId(R.id.intro_phone) } + val screen: Drawable by lazyResettableRegistered { imageDrawable.findDrawableByLayerId(R.id.intro_phone_screen) } + + override fun viewArray(): Array<Array<out View>> + = arrayOf(arrayOf(title), arrayOf(desc)) + + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + title.setText(titleRes) + image.setImageResource(imageRes) + desc.setText(descRes) + super.onViewCreated(view, savedInstanceState) + } + + override fun themeFragmentImpl() { + super.themeFragmentImpl() + title.setTextColor(Prefs.textColor) + desc.setTextColor(Prefs.textColor) + phone.tint(Prefs.textColor) + screen.tint(Prefs.bgColor) + } + + fun themeImageComponent(color: Int, vararg id: Int) { + id.forEach { imageDrawable.findDrawableByLayerId(it).tint(color) } + } + + override fun onPageScrolledImpl(positionOffset: Float) { + super.onPageScrolledImpl(positionOffset) + val alpha = ((1 - Math.abs(positionOffset)) * 255).toInt() + //apply alpha to all layers except the phone base + (0 until imageDrawable.numberOfLayers).forEach { + val d = imageDrawable.getDrawable(it) + if (d != phone) d.alpha = alpha + } + } + + fun firstImageFragmentTransition(offset: Float) { + if (offset < 0) + image.alpha = 1 + offset + } + + fun lastImageFragmentTransition(offset: Float) { + if (offset > 0) + image.alpha = 1 - offset + } +} + +class IntroAccountFragment : BaseImageIntroFragment( + R.string.intro_multiple_accounts, R.drawable.intro_phone_nav, R.string.intro_multiple_accounts_desc +) { + + override fun themeFragmentImpl() { + super.themeFragmentImpl() + themeImageComponent(Prefs.iconColor, R.id.intro_phone_avatar_1, R.id.intro_phone_avatar_2) + themeImageComponent(Prefs.bgColor.colorToForeground(), R.id.intro_phone_nav) + themeImageComponent(Prefs.headerColor, R.id.intro_phone_header) + } + + override fun onPageScrolledImpl(positionOffset: Float) { + super.onPageScrolledImpl(positionOffset) + firstImageFragmentTransition(positionOffset) + } +} + +class IntroTabTouchFragment : BaseImageIntroFragment( + R.string.intro_easy_navigation, R.drawable.intro_phone_tab, R.string.intro_easy_navigation_desc +) { + + override fun themeFragmentImpl() { + super.themeFragmentImpl() + themeImageComponent(Prefs.iconColor, R.id.intro_phone_icon_1, R.id.intro_phone_icon_2, R.id.intro_phone_icon_3, R.id.intro_phone_icon_4) + themeImageComponent(Prefs.headerColor, R.id.intro_phone_tab) + themeImageComponent(Prefs.textColor.withAlpha(80), R.id.intro_phone_icon_ripple) + } +} + +class IntroTabContextFragment : BaseImageIntroFragment( + R.string.intro_context_aware, R.drawable.intro_phone_long_press, R.string.intro_context_aware_desc +) { + + override fun themeFragmentImpl() { + super.themeFragmentImpl() + themeImageComponent(Prefs.headerColor, R.id.intro_phone_toolbar) + themeImageComponent(Prefs.bgColor.colorToForeground(0.1f), R.id.intro_phone_image) + themeImageComponent(Prefs.bgColor.colorToForeground(0.2f), R.id.intro_phone_like, R.id.intro_phone_share) + themeImageComponent(Prefs.bgColor.colorToForeground(0.3f), R.id.intro_phone_comment) + themeImageComponent(Prefs.bgColor.colorToForeground(0.1f), R.id.intro_phone_card_1, R.id.intro_phone_card_2) + themeImageComponent(Prefs.textColor, R.id.intro_phone_image_indicator, R.id.intro_phone_comment_indicator, R.id.intro_phone_card_indicator) + } + + override fun onPageScrolledImpl(positionOffset: Float) { + super.onPageScrolledImpl(positionOffset) + lastImageFragmentTransition(positionOffset) + } +}
\ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt new file mode 100644 index 00000000..552fad3b --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt @@ -0,0 +1,135 @@ +package com.pitchedapps.frost.intro + +import android.annotation.SuppressLint +import android.content.res.ColorStateList +import android.os.Bundle +import android.support.constraint.ConstraintLayout +import android.support.v4.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import ca.allanwang.kau.kotlin.LazyResettableRegistry +import ca.allanwang.kau.utils.Kotterknife +import ca.allanwang.kau.utils.bindViewResettable +import ca.allanwang.kau.utils.setOnSingleTapListener +import com.pitchedapps.frost.R +import com.pitchedapps.frost.activities.IntroActivity +import com.pitchedapps.frost.utils.Prefs +import org.jetbrains.anko.childrenSequence + +/** + * Created by Allan Wang on 2017-07-28. + * + * Contains the base, start, and end fragments + */ + +/** + * The core intro fragment for all other fragments + */ +abstract class BaseIntroFragment(val layoutRes: Int) : Fragment() { + + val screenWidth + get() = resources.displayMetrics.widthPixels + + val lazyRegistry = LazyResettableRegistry() + + protected fun translate(offset: Float, views: Array<Array<out View>>) { + val maxTranslation = offset * screenWidth + val increment = maxTranslation / views.size + views.forEachIndexed { i, group -> + group.forEach { + it.translationX = if (offset > 0) -maxTranslation + i * increment else -(i + 1) * increment + it.alpha = 1 - Math.abs(offset) + } + } + } + + fun <T : Any> lazyResettableRegistered(initializer: () -> T) = lazyRegistry.lazy(initializer) + + /* + * Note that these ids aren't actually inside all layouts + * However, they are in most of them, so they are added here + * for convenience + */ + protected val title: TextView by bindViewResettable(R.id.intro_title) + protected val image: ImageView by bindViewResettable(R.id.intro_image) + protected val desc: TextView by bindViewResettable(R.id.intro_desc) + + protected fun defaultViewArray(): Array<Array<out View>> = arrayOf(arrayOf(title), arrayOf(image), arrayOf(desc)) + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + val view = inflater.inflate(layoutRes, container, false) + return view + } + + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + themeFragment() + } + + override fun onDestroyView() { + super.onDestroyView() + Kotterknife.reset(this) + lazyRegistry.invalidateAll() + } + + fun themeFragment() { + if (view != null) themeFragmentImpl() + } + + protected open fun themeFragmentImpl() { + view?.childrenSequence()?.forEach { (it as? TextView)?.setTextColor(Prefs.textColor) } + } + + protected val viewArray: Array<Array<out View>> by lazyResettableRegistered { viewArray() } + + protected abstract fun viewArray(): Array<Array<out View>> + + fun onPageScrolled(positionOffset: Float) { + if (view != null) onPageScrolledImpl(positionOffset) + } + + protected open fun onPageScrolledImpl(positionOffset: Float) { + translate(positionOffset, viewArray) + } + + fun onPageSelected() { + if (view != null) onPageSelectedImpl() + } + + protected open fun onPageSelectedImpl() { + + } +} + +class IntroFragmentWelcome : BaseIntroFragment(R.layout.intro_welcome) { + + override fun viewArray(): Array<Array<out View>> = defaultViewArray() + + override fun themeFragmentImpl() { + super.themeFragmentImpl() + image.imageTintList = ColorStateList.valueOf(Prefs.textColor) + } +} + +class IntroFragmentEnd : BaseIntroFragment(R.layout.intro_end) { + + val container: ConstraintLayout by bindViewResettable(R.id.intro_end_container) + + override fun viewArray(): Array<Array<out View>> = defaultViewArray() + + override fun themeFragmentImpl() { + super.themeFragmentImpl() + image.imageTintList = ColorStateList.valueOf(Prefs.textColor) + } + + @SuppressLint("ClickableViewAccessibility") + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + container.setOnSingleTapListener { _, event -> + (activity as IntroActivity).finish(event.x, event.y) + } + } +}
\ No newline at end of file |