diff --git a/app/src/main/kotlin/com.jdamcd.sudoku/browse/PuzzleChoiceActivity.kt b/app/src/main/kotlin/com.jdamcd.sudoku/browse/PuzzleChoiceActivity.kt index eabba37..a6d8b0e 100644 --- a/app/src/main/kotlin/com.jdamcd.sudoku/browse/PuzzleChoiceActivity.kt +++ b/app/src/main/kotlin/com.jdamcd.sudoku/browse/PuzzleChoiceActivity.kt @@ -6,6 +6,7 @@ import android.util.Log import android.view.Menu import android.view.MenuItem import android.view.View +import androidx.viewpager2.widget.MarginPageTransformer import com.google.android.play.core.review.ReviewManagerFactory import com.jdamcd.sudoku.R import com.jdamcd.sudoku.app.IntentFactory @@ -77,15 +78,14 @@ class PuzzleChoiceActivity : BaseActivity(), PuzzleChoicePresenter.View { } private fun configurePager() { - val pagerAdapter = PuzzlePagerAdapter(supportFragmentManager, resources) + val pagerAdapter = PuzzlePagerAdapter(this) val pager = binding.pager pager.adapter = pagerAdapter binding.indicator.setViewPager(pager) + pager.offscreenPageLimit = pagerAdapter.itemCount - 1 pager.currentItem = 1 - pager.offscreenPageLimit = pagerAdapter.count - 1 - pager.setPageMarginDrawable(R.drawable.divider_vertical) - pager.pageMargin = ViewUtil.dpToPx(resources, 5) - pager.addOnPageChangeListener(fabView) + pager.setPageTransformer(MarginPageTransformer(ViewUtil.dpToPx(resources, 5))) + pager.registerOnPageChangeCallback(fabView) } override fun onCreateOptionsMenu(menu: Menu): Boolean { diff --git a/app/src/main/kotlin/com.jdamcd.sudoku/browse/PuzzlePagerAdapter.kt b/app/src/main/kotlin/com.jdamcd.sudoku/browse/PuzzlePagerAdapter.kt index cbe02db..1588cdf 100644 --- a/app/src/main/kotlin/com.jdamcd.sudoku/browse/PuzzlePagerAdapter.kt +++ b/app/src/main/kotlin/com.jdamcd.sudoku/browse/PuzzlePagerAdapter.kt @@ -1,17 +1,14 @@ package com.jdamcd.sudoku.browse -import android.content.res.Resources -import androidx.fragment.app.FragmentManager -import androidx.fragment.app.FragmentPagerAdapter +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter import com.jdamcd.sudoku.repository.Level -internal class PuzzlePagerAdapter(fm: FragmentManager, private val resources: Resources) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { +internal class PuzzlePagerAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) { - override fun getItem(position: Int) = PuzzleListFragment.create(levels[position]) + override fun getItemCount() = levels.size - override fun getPageTitle(position: Int): String = resources.getString(levels[position].nameId) - - override fun getCount() = levels.size + override fun createFragment(position: Int) = PuzzleListFragment.create(levels[position]) companion object { val levels = arrayOf(Level.EASY, Level.MEDIUM, Level.HARD, Level.EXTREME) diff --git a/app/src/main/kotlin/com.jdamcd.sudoku/browse/RandomFabView.kt b/app/src/main/kotlin/com.jdamcd.sudoku/browse/RandomFabView.kt index 5133c35..dcd2a10 100644 --- a/app/src/main/kotlin/com.jdamcd.sudoku/browse/RandomFabView.kt +++ b/app/src/main/kotlin/com.jdamcd.sudoku/browse/RandomFabView.kt @@ -3,11 +3,11 @@ package com.jdamcd.sudoku.browse import android.animation.ArgbEvaluator import android.animation.ValueAnimator import android.content.res.ColorStateList -import androidx.viewpager.widget.ViewPager +import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.floatingactionbutton.FloatingActionButton import com.jdamcd.sudoku.R -internal class RandomFabView : ViewPager.OnPageChangeListener { +internal class RandomFabView : ViewPager2.OnPageChangeCallback() { private lateinit var fab: FloatingActionButton private lateinit var fabColours: IntArray @@ -22,10 +22,6 @@ internal class RandomFabView : ViewPager.OnPageChangeListener { return fabColours[position % fabColours.size] } - override fun onPageScrollStateChanged(state: Int) {} - - override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} - override fun onPageSelected(position: Int) { animateBackgroundChange(position) } diff --git a/app/src/main/kotlin/com.jdamcd.sudoku/browse/indicator/PageIndicator.kt b/app/src/main/kotlin/com.jdamcd.sudoku/browse/indicator/PageIndicator.kt index f3403bb..9da5d08 100644 --- a/app/src/main/kotlin/com.jdamcd.sudoku/browse/indicator/PageIndicator.kt +++ b/app/src/main/kotlin/com.jdamcd.sudoku/browse/indicator/PageIndicator.kt @@ -1,17 +1,16 @@ package com.jdamcd.sudoku.browse.indicator -import androidx.viewpager.widget.ViewPager -import androidx.viewpager.widget.ViewPager.OnPageChangeListener +import androidx.viewpager2.widget.ViewPager2 -interface PageIndicator : OnPageChangeListener { +interface PageIndicator { - fun setViewPager(view: ViewPager) + fun setViewPager(view: ViewPager2) - fun setViewPager(view: ViewPager, initialPosition: Int) + fun setViewPager(view: ViewPager2, initialPosition: Int) fun setCurrentItem(item: Int) - fun setOnPageChangeListener(listener: OnPageChangeListener) + fun setOnPageChangeCallback(listener: ViewPager2.OnPageChangeCallback) fun notifyDataSetChanged() } diff --git a/app/src/main/kotlin/com.jdamcd.sudoku/browse/indicator/PagerStripIndicator.kt b/app/src/main/kotlin/com.jdamcd.sudoku/browse/indicator/PagerStripIndicator.kt index 21b6d4f..34dfbf3 100644 --- a/app/src/main/kotlin/com.jdamcd.sudoku/browse/indicator/PagerStripIndicator.kt +++ b/app/src/main/kotlin/com.jdamcd.sudoku/browse/indicator/PagerStripIndicator.kt @@ -15,8 +15,8 @@ import android.widget.HorizontalScrollView import android.widget.LinearLayout import android.widget.TextView import androidx.core.widget.TextViewCompat -import androidx.viewpager.widget.ViewPager -import androidx.viewpager.widget.ViewPager.OnPageChangeListener +import androidx.viewpager2.widget.ViewPager2 +import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback import com.jdamcd.sudoku.R import com.jdamcd.sudoku.util.ViewUtil @@ -24,8 +24,8 @@ class PagerStripIndicator @JvmOverloads constructor(context: Context, attrs: Att private val tabLayoutParams: LinearLayout.LayoutParams - private var pager: ViewPager? = null - private var listener: OnPageChangeListener? = null + private var pager: ViewPager2? = null + private var listener: OnPageChangeCallback? = null private val tabsContainer: LinearLayout @@ -33,12 +33,14 @@ class PagerStripIndicator @JvmOverloads constructor(context: Context, attrs: Att private lateinit var rectPaint: Paint private var tabBackground: Int = 0 private var tabTextColour = -0x99999a - private val indicatorColours: IntArray private var tabTextSize = 12 private var scrollOffset = 52 private var indicatorHeight = 8 private var tabPadding = 24 + private val indicatorColours: IntArray + private val indicatorTitles: Array + private var currentPosition = 0 private var currentPositionOffset = 0f private var lastScrollX = 0 @@ -59,6 +61,7 @@ class PagerStripIndicator @JvmOverloads constructor(context: Context, attrs: Att initSystemAttributes(context, attrs) indicatorColours = resources.getIntArray(R.array.tab_colours) + indicatorTitles = resources.getStringArray(R.array.tab_titles) tabLayoutParams = LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f) } @@ -85,17 +88,17 @@ class PagerStripIndicator @JvmOverloads constructor(context: Context, attrs: Att a.recycle() } - override fun setViewPager(view: ViewPager) { + override fun setViewPager(view: ViewPager2) { if (pager === view) { return } view.adapter ?: throw IllegalStateException("ViewPager does not have adapter instance.") this.pager = view - view.addOnPageChangeListener(this) + view.registerOnPageChangeCallback(CallbackWrapper()) notifyDataSetChanged() } - override fun setViewPager(view: ViewPager, initialPosition: Int) { + override fun setViewPager(view: ViewPager2, initialPosition: Int) { setViewPager(view) setCurrentItem(initialPosition) } @@ -105,7 +108,7 @@ class PagerStripIndicator @JvmOverloads constructor(context: Context, attrs: Att requestLayout() } - override fun setOnPageChangeListener(listener: OnPageChangeListener) { + override fun setOnPageChangeCallback(listener: OnPageChangeCallback) { this.listener = listener } @@ -113,9 +116,9 @@ class PagerStripIndicator @JvmOverloads constructor(context: Context, attrs: Att override fun notifyDataSetChanged() { tabsContainer.removeAllViews() - tabCount = pager?.adapter!!.count + tabCount = pager?.adapter!!.itemCount for (i in 0 until tabCount) { - addTextTab(i, pager?.adapter!!.getPageTitle(i).toString()) + addTextTab(i) } updateTabStyles() @@ -132,9 +135,9 @@ class PagerStripIndicator @JvmOverloads constructor(context: Context, attrs: Att ) } - private fun addTextTab(position: Int, title: String) { + private fun addTextTab(position: Int) { val tab = TextView(context) - tab.text = title + tab.text = indicatorTitles[position] tab.gravity = Gravity.CENTER TextViewCompat.setTextAppearance(tab, R.style.TabText) tab.setOnClickListener { pager!!.currentItem = position } @@ -218,32 +221,6 @@ class PagerStripIndicator @JvmOverloads constructor(context: Context, attrs: Att return indicatorColours[position % indicatorColours.size] } - override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { - currentPosition = position - currentPositionOffset = positionOffset - - if (currentPositionOffset == 1.0f) { - currentPosition++ - currentPositionOffset = 0f - } - - scrollToChild(position, (positionOffset * tabsContainer.getChildAt(position).width).toInt()) - invalidate() - - listener?.onPageScrolled(position, positionOffset, positionOffsetPixels) - } - - override fun onPageScrollStateChanged(state: Int) { - if (state == ViewPager.SCROLL_STATE_IDLE) { - scrollToChild(pager!!.currentItem, 0) - } - listener?.onPageScrollStateChanged(state) - } - - override fun onPageSelected(position: Int) { - listener?.onPageSelected(position) - } - public override fun onRestoreInstanceState(state: Parcelable) { val savedState = state as SavedState super.onRestoreInstanceState(savedState.superState) @@ -258,6 +235,34 @@ class PagerStripIndicator @JvmOverloads constructor(context: Context, attrs: Att return savedState } + private inner class CallbackWrapper : OnPageChangeCallback() { + override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { + currentPosition = position + currentPositionOffset = positionOffset + + if (currentPositionOffset == 1.0f) { + currentPosition++ + currentPositionOffset = 0f + } + + scrollToChild(position, (positionOffset * tabsContainer.getChildAt(position).width).toInt()) + invalidate() + + listener?.onPageScrolled(position, positionOffset, positionOffsetPixels) + } + + override fun onPageScrollStateChanged(state: Int) { + if (state == ViewPager2.SCROLL_STATE_IDLE) { + scrollToChild(pager!!.currentItem, 0) + } + listener?.onPageScrollStateChanged(state) + } + + override fun onPageSelected(position: Int) { + listener?.onPageSelected(position) + } + } + private class SavedState : BaseSavedState { var currentPosition: Int = 0 diff --git a/app/src/main/res/drawable-hdpi/divider_vertical.9.png b/app/src/main/res/drawable-hdpi/divider_vertical.9.png deleted file mode 100644 index 0279e17..0000000 Binary files a/app/src/main/res/drawable-hdpi/divider_vertical.9.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/divider_vertical.9.png b/app/src/main/res/drawable-mdpi/divider_vertical.9.png deleted file mode 100644 index 0279e17..0000000 Binary files a/app/src/main/res/drawable-mdpi/divider_vertical.9.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/divider_vertical.9.png b/app/src/main/res/drawable-xhdpi/divider_vertical.9.png deleted file mode 100644 index 65061c0..0000000 Binary files a/app/src/main/res/drawable-xhdpi/divider_vertical.9.png and /dev/null differ diff --git a/app/src/main/res/layout/activity_puzzle_choice.xml b/app/src/main/res/layout/activity_puzzle_choice.xml index 6ac9050..0684429 100644 --- a/app/src/main/res/layout/activity_puzzle_choice.xml +++ b/app/src/main/res/layout/activity_puzzle_choice.xml @@ -21,7 +21,7 @@ style="@style/PagerIndicator" /> - diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index e4c7aff..023edaf 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -16,6 +16,13 @@ @color/extreme + + @string/level_easy + @string/level_medium + @string/level_hard + @string/level_extreme + + @string/puzzle_complete_1 @string/puzzle_complete_2