Make pager a completely separate class for easier reuse
This commit is contained in:
parent
53efffde51
commit
59975c77f4
1 changed files with 285 additions and 268 deletions
|
@ -11,6 +11,7 @@ import android.content.Context
|
||||||
import android.graphics.*
|
import android.graphics.*
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
import android.text.Layout
|
import android.text.Layout
|
||||||
import android.text.StaticLayout
|
import android.text.StaticLayout
|
||||||
import android.text.TextPaint
|
import android.text.TextPaint
|
||||||
|
@ -67,7 +68,14 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
private var redrawWidgets = false
|
private var redrawWidgets = false
|
||||||
private var iconSize = 0
|
private var iconSize = 0
|
||||||
|
|
||||||
private val pager = Pager()
|
private val pager = AnimatedGridPager(
|
||||||
|
getMaxPage = ::getMaxPage,
|
||||||
|
redrawGrid = ::redrawGrid,
|
||||||
|
getWidth = { width },
|
||||||
|
getHandler = { handler },
|
||||||
|
getNextPageBound = { right - sideMargins.right - cellWidth / 2 },
|
||||||
|
getPrevPageBound = { left + sideMargins.left + cellWidth / 2 }
|
||||||
|
)
|
||||||
|
|
||||||
// apply fake margins at the home screen. Real ones would cause the icons be cut at dragging at screen sides
|
// apply fake margins at the home screen. Real ones would cause the icons be cut at dragging at screen sides
|
||||||
var sideMargins = Rect()
|
var sideMargins = Rect()
|
||||||
|
@ -203,7 +211,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draggedItemCurrentCoords.first == -1 && draggedItemCurrentCoords.second == -1 && draggedItem != null) {
|
if (draggedItemCurrentCoords.first == -1 && draggedItemCurrentCoords.second == -1) {
|
||||||
if (draggedItem!!.type == ITEM_TYPE_WIDGET) {
|
if (draggedItem!!.type == ITEM_TYPE_WIDGET) {
|
||||||
val draggedWidgetView = widgetViews.firstOrNull { it.tag == draggedItem?.widgetId }
|
val draggedWidgetView = widgetViews.firstOrNull { it.tag == draggedItem?.widgetId }
|
||||||
if (draggedWidgetView != null) {
|
if (draggedWidgetView != null) {
|
||||||
|
@ -965,14 +973,40 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
|
|
||||||
|
|
||||||
fun setSwipeMovement(diffX: Float) {
|
fun setSwipeMovement(diffX: Float) {
|
||||||
|
if (draggedItem != null) {
|
||||||
pager.setSwipeMovement(diffX)
|
pager.setSwipeMovement(diffX)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun finalizeSwipe() {
|
fun finalizeSwipe() {
|
||||||
pager.finalizeSwipe()
|
pager.finalizeSwipe()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class responsible for managing current page and providing utilities for animating page changes,
|
||||||
|
* as well as partial dragigng between pages
|
||||||
|
*/
|
||||||
|
private class AnimatedGridPager(
|
||||||
|
private val getMaxPage: () -> Int,
|
||||||
|
private val redrawGrid: () -> Unit,
|
||||||
|
private val getWidth: () -> Int,
|
||||||
|
private val getHandler: () -> Handler,
|
||||||
|
private val getNextPageBound: () -> Int,
|
||||||
|
private val getPrevPageBound: () -> Int,
|
||||||
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val PAGE_CHANGE_HOLD_THRESHOLD = 500L
|
||||||
|
private const val PAGE_INDICATORS_FADE_DELAY = PAGE_CHANGE_HOLD_THRESHOLD + 300L
|
||||||
|
|
||||||
|
private enum class PageChangeArea {
|
||||||
|
LEFT,
|
||||||
|
MIDDLE,
|
||||||
|
RIGHT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private inner class Pager {
|
|
||||||
private var lastPage = 0
|
private var lastPage = 0
|
||||||
private var currentPage = 0
|
private var currentPage = 0
|
||||||
private var pageChangeLastArea = PageChangeArea.MIDDLE
|
private var pageChangeLastArea = PageChangeArea.MIDDLE
|
||||||
|
@ -988,7 +1022,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
|
|
||||||
fun isItemOnLastPage(item: HomeScreenGridItem) = item.page == lastPage
|
fun isItemOnLastPage(item: HomeScreenGridItem) = item.page == lastPage
|
||||||
|
|
||||||
fun getPageCount() = max(getMaxPage(), pager.currentPage) + 1
|
fun getPageCount() = max(getMaxPage(), currentPage) + 1
|
||||||
|
|
||||||
|
|
||||||
fun isOutsideOfPageRange() = currentPage > getMaxPage()
|
fun isOutsideOfPageRange() = currentPage > getMaxPage()
|
||||||
|
@ -998,12 +1032,12 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
|
|
||||||
fun isSwiped() = abs(pageChangeSwipedPercentage) > 0f
|
fun isSwiped() = abs(pageChangeSwipedPercentage) > 0f
|
||||||
|
|
||||||
fun isAnimatingPageChange() = pager.pageChangeAnimLeftPercentage > 0f
|
fun isAnimatingPageChange() = pageChangeAnimLeftPercentage > 0f
|
||||||
|
|
||||||
fun shouldDisplayPageChangeIndicator() = isSwiped() || isAnimatingPageChange() || pageChangeIndicatorsAlpha > 0f
|
fun shouldDisplayPageChangeIndicator() = isSwiped() || isAnimatingPageChange() || pageChangeIndicatorsAlpha > 0f
|
||||||
|
|
||||||
fun getPageChangeIndicatorsAlpha() = if (pageChangeIndicatorsAlpha != 0f) {
|
fun getPageChangeIndicatorsAlpha() = if (pageChangeIndicatorsAlpha != 0f) {
|
||||||
(pager.pageChangeIndicatorsAlpha * 255.0f).toInt()
|
(pageChangeIndicatorsAlpha * 255.0f).toInt()
|
||||||
} else {
|
} else {
|
||||||
255
|
255
|
||||||
}
|
}
|
||||||
|
@ -1053,12 +1087,12 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setSwipeMovement(diffX: Float) {
|
fun setSwipeMovement(diffX: Float) {
|
||||||
if (!pageChangeEnabled || draggedItem != null) {
|
if (!pageChangeEnabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentPage < getMaxPage() && diffX > 0f || currentPage > 0 && diffX < 0f) {
|
if (currentPage < getMaxPage() && diffX > 0f || currentPage > 0 && diffX < 0f) {
|
||||||
pageChangeSwipedPercentage = (-diffX / width.toFloat()).coerceIn(-1f, 1f)
|
pageChangeSwipedPercentage = (-diffX / getWidth().toFloat()).coerceIn(-1f, 1f)
|
||||||
redrawGrid()
|
redrawGrid()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1089,11 +1123,11 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
|
|
||||||
fun handleItemMovement(x: Int, y: Int) {
|
fun handleItemMovement(x: Int, y: Int) {
|
||||||
showIndicators()
|
showIndicators()
|
||||||
if (x > right - sideMargins.right - cellWidth / 2) {
|
if (x > getNextPageBound()) {
|
||||||
doWithPageChangeDelay(PageChangeArea.RIGHT) {
|
doWithPageChangeDelay(PageChangeArea.RIGHT) {
|
||||||
nextOrAdditionalPage()
|
nextOrAdditionalPage()
|
||||||
}
|
}
|
||||||
} else if (x < left + sideMargins.left + cellWidth / 2) {
|
} else if (x < getPrevPageBound()) {
|
||||||
doWithPageChangeDelay(PageChangeArea.LEFT) {
|
doWithPageChangeDelay(PageChangeArea.LEFT) {
|
||||||
prevPage()
|
prevPage()
|
||||||
}
|
}
|
||||||
|
@ -1162,23 +1196,23 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
|
|
||||||
private fun showIndicators() {
|
private fun showIndicators() {
|
||||||
pageChangeIndicatorsAlpha = 1f
|
pageChangeIndicatorsAlpha = 1f
|
||||||
removeCallbacks(startFadingIndicators)
|
getHandler().removeCallbacks(startFadingIndicators)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun clearPageChangeFlags() {
|
private fun clearPageChangeFlags() {
|
||||||
pageChangeLastArea = PageChangeArea.MIDDLE
|
pageChangeLastArea = PageChangeArea.MIDDLE
|
||||||
pageChangeLastAreaEntryTime = 0
|
pageChangeLastAreaEntryTime = 0
|
||||||
removeCallbacks(checkAndExecuteDelayedPageChange)
|
getHandler().removeCallbacks(checkAndExecuteDelayedPageChange)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun schedulePageChange() {
|
private fun schedulePageChange() {
|
||||||
pageChangeLastAreaEntryTime = System.currentTimeMillis()
|
pageChangeLastAreaEntryTime = System.currentTimeMillis()
|
||||||
postDelayed(checkAndExecuteDelayedPageChange, PAGE_CHANGE_HOLD_THRESHOLD)
|
getHandler().postDelayed(checkAndExecuteDelayedPageChange, PAGE_CHANGE_HOLD_THRESHOLD)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scheduleIndicatorsFade() {
|
private fun scheduleIndicatorsFade() {
|
||||||
pageChangeIndicatorsAlpha = 1f
|
pageChangeIndicatorsAlpha = 1f
|
||||||
postDelayed(startFadingIndicators, PAGE_INDICATORS_FADE_DELAY)
|
getHandler().postDelayed(startFadingIndicators, PAGE_INDICATORS_FADE_DELAY)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doWithPageChangeDelay(needed: PageChangeArea, pageChangeFunction: () -> Boolean) {
|
private fun doWithPageChangeDelay(needed: PageChangeArea, pageChangeFunction: () -> Boolean) {
|
||||||
|
@ -1208,7 +1242,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
pageChangeIndicatorsAlpha = 0f
|
pageChangeIndicatorsAlpha = 0f
|
||||||
val startingAt = 1 - abs(pageChangeSwipedPercentage)
|
val startingAt = 1 - abs(pageChangeSwipedPercentage)
|
||||||
pageChangeSwipedPercentage = 0f
|
pageChangeSwipedPercentage = 0f
|
||||||
removeCallbacks(startFadingIndicators)
|
getHandler().removeCallbacks(startFadingIndicators)
|
||||||
if (redraw) {
|
if (redraw) {
|
||||||
redrawGrid()
|
redrawGrid()
|
||||||
}
|
}
|
||||||
|
@ -1224,11 +1258,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
pageChangeAnimLeftPercentage = 0f
|
pageChangeAnimLeftPercentage = 0f
|
||||||
pageChangeEnabled = true
|
pageChangeEnabled = true
|
||||||
lastPage = currentPage
|
lastPage = currentPage
|
||||||
if (draggedItem != null) {
|
|
||||||
schedulePageChange()
|
|
||||||
} else {
|
|
||||||
clearPageChangeFlags()
|
clearPageChangeFlags()
|
||||||
}
|
|
||||||
scheduleIndicatorsFade()
|
scheduleIndicatorsFade()
|
||||||
redrawGrid()
|
redrawGrid()
|
||||||
}
|
}
|
||||||
|
@ -1236,17 +1266,4 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
|
||||||
start()
|
start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val PAGE_CHANGE_HOLD_THRESHOLD = 500L
|
|
||||||
private const val PAGE_INDICATORS_FADE_DELAY = PAGE_CHANGE_HOLD_THRESHOLD + 300L
|
|
||||||
|
|
||||||
private enum class PageChangeArea {
|
|
||||||
LEFT,
|
|
||||||
MIDDLE,
|
|
||||||
RIGHT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue