diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt index 68c702c0..3f26b19d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SubscriptionFragment.kt @@ -31,10 +31,16 @@ import net.pokeranalytics.android.util.Preferences import net.pokeranalytics.android.util.billing.AppGuard import net.pokeranalytics.android.util.billing.IAPProducts import net.pokeranalytics.android.util.billing.PurchaseDelegate +import java.lang.ref.WeakReference import java.time.Period class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListener, PurchaseDelegate, ViewPager.OnPageChangeListener { + companion object { + val parallax: Float = 64f.px + } + + private var pagerAdapter: ScreenSlidePagerAdapter? = null private var selectedProduct: SkuDetails? = null override fun onCreate(savedInstanceState: Bundle?) { @@ -85,7 +91,7 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene // Pager // The pager adapter, which provides the pages to the view pager widget. - val pagerAdapter = ScreenSlidePagerAdapter(requireFragmentManager()) + this.pagerAdapter = ScreenSlidePagerAdapter(requireFragmentManager()) this.pager.adapter = pagerAdapter this.pager.addOnPageChangeListener(this) @@ -108,7 +114,7 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene this.pageIndicator.addView(view, layoutParam) } - this.changeColorOfIndicator(0) + this.updatePagerIndicators(0) } @@ -118,13 +124,21 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene */ private inner class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { + private var fragments: HashMap> = HashMap() + private inner class FeatureDescriptor(var iconResId: Int, var titleResId: Int, var descResId: Int) + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val fragment = super.instantiateItem(container, position) as ScreenSlidePageFragment + fragments[position] = WeakReference(fragment) + return super.instantiateItem(container, position) + } + private val dataSource: List = listOf( - FeatureDescriptor(R.drawable.ic_baseline_all_inclusive_24px, R.string.f_unlimited, R.string.f_unlimited_desc), - FeatureDescriptor(R.drawable.ic_baseline_wifi_off_24px, R.string.f_offline, R.string.f_offline_desc), - FeatureDescriptor(R.drawable.ic_baseline_vpn_key_24px, R.string.f_privacy, R.string.f_privacy_desc), - FeatureDescriptor(R.drawable.ic_baseline_email_24px, R.string.f_support, R.string.f_support_desc) + FeatureDescriptor(R.drawable.ic_baseline_all_inclusive, R.string.f_unlimited, R.string.f_unlimited_desc), + FeatureDescriptor(R.drawable.ic_baseline_wifi_off, R.string.f_offline, R.string.f_offline_desc), + FeatureDescriptor(R.drawable.ic_baseline_vpn_key, R.string.f_privacy, R.string.f_privacy_desc), + FeatureDescriptor(R.drawable.ic_baseline_email, R.string.f_support, R.string.f_support_desc) ) override fun getCount(): Int = this.dataSource.size @@ -133,21 +147,27 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene return ScreenSlidePageFragment(d.iconResId, d.titleResId, d.descResId) } + /** + * Return the fragment at [position] + */ + fun getFragment(position: Int): ScreenSlidePageFragment? { + if (fragments.contains(position)) { + return fragments[position]?.get() + } + return null + } } // SkuDetailsResponseListener override fun onSkuDetailsResponse(responseCode: Int, skuDetailsList: MutableList?) { - if (responseCode == BillingClient.BillingResponse.OK && skuDetailsList != null) { this.hideLoader() selectedProduct = skuDetailsList.first { it.sku == IAPProducts.PRO.identifier } updateUI() } - } private fun updateUI() { - this.selectedProduct?.let { this.purchase.isEnabled = true val perYearString = requireContext().getString(R.string.year_subscription) @@ -162,9 +182,7 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene val formattedFreeTrial = "$freeTrialDays " + requireContext().getString(R.string.days) + " " + requireContext().getString(R.string.free_trial) this.freetrial.text = formattedFreeTrial - } - } // PurchaseDelegate @@ -182,22 +200,30 @@ class SubscriptionFragment : PokerAnalyticsFragment(), SkuDetailsResponseListene override fun onPageScrollStateChanged(state: Int) {} - override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} + override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { + pagerAdapter?.getFragment(position)?.let { + it.updateViewsPosition(-positionOffset * parallax) + } + pagerAdapter?.getFragment(position + 1)?.let { + it.updateViewsPosition((1 - positionOffset) * parallax) + } + } override fun onPageSelected(position: Int) { - this.changeColorOfIndicator(position) + updatePagerIndicators(position) } - private fun changeColorOfIndicator(position: Int) { + private fun updatePagerIndicators(position: Int) { this.pageIndicator.children.forEachIndexed { index, view -> val drawable = view.background when (drawable) { is GradientDrawable -> { val color = if (position == index) R.color.white else R.color.quantum_grey drawable.setColor(requireContext().getColor(color)) - } else -> {} + } + else -> { + } } - } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/ScreenSlidePageFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/ScreenSlidePageFragment.kt index 326c6a05..534fed12 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/ScreenSlidePageFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/components/ScreenSlidePageFragment.kt @@ -22,6 +22,15 @@ class ScreenSlidePageFragment(var iconResId: Int, var titleResId: Int, var descr this.icon.setImageResource(this.iconResId) this.title.text = requireContext().getString(this.titleResId) this.description.text = requireContext().getString(this.descriptionResId) + } + + /** + * Update views position + */ + fun updateViewsPosition(position: Float) { + view?.findViewById(R.id.title)?.translationX = position + view?.findViewById(R.id.icon)?.translationX = position + view?.findViewById(R.id.description)?.translationX = position * 2f } diff --git a/app/src/main/res/layout/fragment_screen_slide_page.xml b/app/src/main/res/layout/fragment_screen_slide_page.xml index d0aec965..569f77bc 100644 --- a/app/src/main/res/layout/fragment_screen_slide_page.xml +++ b/app/src/main/res/layout/fragment_screen_slide_page.xml @@ -1,50 +1,53 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/content" + android:layout_width="match_parent" + android:layout_height="match_parent"> - + - + - + - + - + diff --git a/app/src/main/res/layout/fragment_subscription.xml b/app/src/main/res/layout/fragment_subscription.xml index 3603c7b5..587cb8e5 100644 --- a/app/src/main/res/layout/fragment_subscription.xml +++ b/app/src/main/res/layout/fragment_subscription.xml @@ -39,23 +39,28 @@ + app:layout_constraintHeight_percent="0.6" + app:layout_constraintVertical_bias="0.4" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/freetrial" /> + app:layout_constraintTop_toBottomOf="@id/pager" />