mirror of
				https://github.com/SimpleMobileTools/Simple-Launcher.git
				synced 2025-06-05 21:59:15 +02:00 
			
		
		
		
	Handle home screen pages dragging
This commit is contained in:
		| @@ -60,6 +60,8 @@ class MainActivity : SimpleActivity(), FlingListener { | |||||||
|     private var mMoveGestureThreshold = 0 |     private var mMoveGestureThreshold = 0 | ||||||
|     private var mIgnoreUpEvent = false |     private var mIgnoreUpEvent = false | ||||||
|     private var mIgnoreMoveEvents = false |     private var mIgnoreMoveEvents = false | ||||||
|  |     private var mIgnoreXMoveEvents = false | ||||||
|  |     private var mIgnoreYMoveEvents = false | ||||||
|     private var mLongPressedIcon: HomeScreenGridItem? = null |     private var mLongPressedIcon: HomeScreenGridItem? = null | ||||||
|     private var mOpenPopupMenu: PopupMenu? = null |     private var mOpenPopupMenu: PopupMenu? = null | ||||||
|     private var mCachedLaunchers = ArrayList<AppLauncher>() |     private var mCachedLaunchers = ArrayList<AppLauncher>() | ||||||
| @@ -362,13 +364,20 @@ class MainActivity : SimpleActivity(), FlingListener { | |||||||
|  |  | ||||||
|                 if (hasFingerMoved && !mIgnoreMoveEvents) { |                 if (hasFingerMoved && !mIgnoreMoveEvents) { | ||||||
|                     val diffY = mTouchDownY - event.y |                     val diffY = mTouchDownY - event.y | ||||||
|  |                     val diffX = mTouchDownX - event.x | ||||||
|  |  | ||||||
|                     if (isWidgetsFragmentExpanded()) { |                     if (abs(diffY) > abs(diffX) && !mIgnoreYMoveEvents) { | ||||||
|                         val newY = mWidgetsFragmentY - diffY |                         mIgnoreXMoveEvents = true | ||||||
|                         binding.widgetsFragment.root.y = Math.min(Math.max(0f, newY), mScreenHeight.toFloat()) |                         if (isWidgetsFragmentExpanded()) { | ||||||
|                     } else if (mLongPressedIcon == null) { |                             val newY = mWidgetsFragmentY - diffY | ||||||
|                         val newY = mAllAppsFragmentY - diffY |                             binding.widgetsFragment.root.y = Math.min(Math.max(0f, newY), mScreenHeight.toFloat()) | ||||||
|                         binding.allAppsFragment.root.y = Math.min(Math.max(0f, newY), mScreenHeight.toFloat()) |                         } else if (mLongPressedIcon == null) { | ||||||
|  |                             val newY = mAllAppsFragmentY - diffY | ||||||
|  |                             binding.allAppsFragment.root.y = Math.min(Math.max(0f, newY), mScreenHeight.toFloat()) | ||||||
|  |                         } | ||||||
|  |                     } else if (abs(diffX) > abs(diffY) && !mIgnoreXMoveEvents) { | ||||||
|  |                         mIgnoreYMoveEvents = true | ||||||
|  |                         binding.homeScreenGrid.root.setSwipeMovement(diffX) | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| @@ -386,18 +395,27 @@ class MainActivity : SimpleActivity(), FlingListener { | |||||||
|                 binding.homeScreenGrid.root.itemDraggingStopped() |                 binding.homeScreenGrid.root.itemDraggingStopped() | ||||||
|  |  | ||||||
|                 if (!mIgnoreUpEvent) { |                 if (!mIgnoreUpEvent) { | ||||||
|                     if (binding.allAppsFragment.root.y < mScreenHeight * 0.5) { |                     if (!mIgnoreYMoveEvents) { | ||||||
|                         showFragment(binding.allAppsFragment) |                         if (binding.allAppsFragment.root.y < mScreenHeight * 0.5) { | ||||||
|                     } else if (isAllAppsFragmentExpanded()) { |                             showFragment(binding.allAppsFragment) | ||||||
|                         hideFragment(binding.allAppsFragment) |                         } else if (isAllAppsFragmentExpanded()) { | ||||||
|  |                             hideFragment(binding.allAppsFragment) | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                         if (binding.widgetsFragment.root.y < mScreenHeight * 0.5) { | ||||||
|  |                             showFragment(binding.widgetsFragment) | ||||||
|  |                         } else if (isWidgetsFragmentExpanded()) { | ||||||
|  |                             hideFragment(binding.widgetsFragment) | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     if (binding.widgetsFragment.root.y < mScreenHeight * 0.5) { |                     if (!mIgnoreXMoveEvents) { | ||||||
|                         showFragment(binding.widgetsFragment) |                         binding.homeScreenGrid.root.finalizeSwipe() | ||||||
|                     } else if (isWidgetsFragmentExpanded()) { |  | ||||||
|                         hideFragment(binding.widgetsFragment) |  | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  |                 mIgnoreXMoveEvents = false | ||||||
|  |                 mIgnoreYMoveEvents = false | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -37,10 +37,7 @@ import com.simplemobiletools.launcher.extensions.getDrawableForPackageName | |||||||
| import com.simplemobiletools.launcher.extensions.homeScreenGridItemsDB | import com.simplemobiletools.launcher.extensions.homeScreenGridItemsDB | ||||||
| import com.simplemobiletools.launcher.helpers.* | import com.simplemobiletools.launcher.helpers.* | ||||||
| import com.simplemobiletools.launcher.models.HomeScreenGridItem | import com.simplemobiletools.launcher.models.HomeScreenGridItem | ||||||
| import kotlin.math.abs | import kotlin.math.* | ||||||
| import kotlin.math.floor |  | ||||||
| import kotlin.math.max |  | ||||||
| import kotlin.math.min |  | ||||||
|  |  | ||||||
| class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : RelativeLayout(context, attrs, defStyle) { | class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : RelativeLayout(context, attrs, defStyle) { | ||||||
|     constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0) |     constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0) | ||||||
| @@ -77,6 +74,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|     private var pageChangeAnimLeftPercentage = 0f |     private var pageChangeAnimLeftPercentage = 0f | ||||||
|     private var pageChangeEnabled = true |     private var pageChangeEnabled = true | ||||||
|     private var pageChangeIndicatorsAlpha = 0f |     private var pageChangeIndicatorsAlpha = 0f | ||||||
|  |     private var pageChangeSwipedPercentage = 0f | ||||||
|  |  | ||||||
|     // 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() | ||||||
| @@ -611,21 +609,12 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|  |  | ||||||
|     private fun updateWidgetPositionAndSize(widgetView: AppWidgetHostView, item: HomeScreenGridItem): Size { |     private fun updateWidgetPositionAndSize(widgetView: AppWidgetHostView, item: HomeScreenGridItem): Size { | ||||||
|         var x = calculateWidgetX(item.left) + width * item.page - width * lastPage |         var x = calculateWidgetX(item.left) + width * item.page - width * lastPage | ||||||
|         if (pageChangeAnimLeftPercentage > 0f && pageChangeAnimLeftPercentage < 1f && (item.page == currentPage || item.page == lastPage)) { |         if (isBetweenPages() && (item.page == currentPage || item.page == lastPage || (pageChangeSwipedPercentage > 0f && item.page == currentPage - 1) || (pageChangeSwipedPercentage < 0f && item.page == currentPage + 1))) { | ||||||
|             val xFactor = if (currentPage > lastPage) { |             val xFactor = getXFactorForCurrentPage() | ||||||
|                 pageChangeAnimLeftPercentage |             val lastXFactor = getXFactorForLastPage() | ||||||
|             } else { |  | ||||||
|                 -pageChangeAnimLeftPercentage |  | ||||||
|             } |  | ||||||
|             val lastXFactor = if (currentPage > lastPage) { |  | ||||||
|                 pageChangeAnimLeftPercentage - 1 |  | ||||||
|             } else { |  | ||||||
|                 1 - pageChangeAnimLeftPercentage |  | ||||||
|             } |  | ||||||
|             if (item.page == currentPage) { |             if (item.page == currentPage) { | ||||||
|                 x += width * xFactor |                 x += width * xFactor | ||||||
|             } |             } else if (item.page == lastPage || (pageChangeSwipedPercentage > 0f && item.page == currentPage - 1) || (pageChangeSwipedPercentage < 0f && item.page == currentPage + 1)) { | ||||||
|             if (item.page == lastPage) { |  | ||||||
|                 x += width * lastXFactor |                 x += width * lastXFactor | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -685,16 +674,8 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|             fillCellSizes() |             fillCellSizes() | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         val currentXFactor = if (currentPage > lastPage) { |         val currentXFactor = getXFactorForCurrentPage() | ||||||
|             pageChangeAnimLeftPercentage |         val lastXFactor = getXFactorForLastPage() | ||||||
|         } else { |  | ||||||
|             -pageChangeAnimLeftPercentage |  | ||||||
|         } |  | ||||||
|         val lastXFactor = if (currentPage > lastPage) { |  | ||||||
|             pageChangeAnimLeftPercentage - 1 |  | ||||||
|         } else { |  | ||||||
|             1 - pageChangeAnimLeftPercentage |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         fun handleItemDrawing(item: HomeScreenGridItem, xFactor: Float) { |         fun handleItemDrawing(item: HomeScreenGridItem, xFactor: Float) { | ||||||
|             if (item.id != draggedItem?.id) { |             if (item.id != draggedItem?.id) { | ||||||
| @@ -755,6 +736,20 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if (abs(pageChangeSwipedPercentage) > 0f) { | ||||||
|  |             gridItems.filter { | ||||||
|  |                 (it.drawable != null && it.type == ITEM_TYPE_ICON || it.type == ITEM_TYPE_SHORTCUT) | ||||||
|  |                     && ((pageChangeSwipedPercentage > 0f && it.page == currentPage - 1) || (pageChangeSwipedPercentage < 0f && it.page == currentPage + 1)) | ||||||
|  |                     && !it.docked | ||||||
|  |             }.forEach { item -> | ||||||
|  |                 if (item.outOfBounds()) { | ||||||
|  |                     return@forEach | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 handleItemDrawing(item, lastXFactor) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if (isFirstDraw) { |         if (isFirstDraw) { | ||||||
|             gridItems.filter { it.type == ITEM_TYPE_WIDGET && !it.outOfBounds() }.forEach { item -> |             gridItems.filter { it.type == ITEM_TYPE_WIDGET && !it.outOfBounds() }.forEach { item -> | ||||||
|                 bindWidget(item, true) |                 bindWidget(item, true) | ||||||
| @@ -768,7 +763,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Only draw page indicators when there is a need for it |         // Only draw page indicators when there is a need for it | ||||||
|         if (pageChangeAnimLeftPercentage > 0f || pageChangeIndicatorsAlpha != 0f) { |         if (pageChangeAnimLeftPercentage > 0f || pageChangeIndicatorsAlpha != 0f || abs(pageChangeSwipedPercentage) > 0f) { | ||||||
|             val pageCount = max(getMaxPage(), currentPage) + 1 |             val pageCount = max(getMaxPage(), currentPage) + 1 | ||||||
|             val pageIndicatorsRequiredWidth = pageCount * pageIndicatorRadius * 2 + pageCount * (pageIndicatorMargin - 1) |             val pageIndicatorsRequiredWidth = pageCount * pageIndicatorRadius * 2 + pageCount * (pageIndicatorMargin - 1) | ||||||
|             val usableWidth = getFakeWidth() |             val usableWidth = getFakeWidth() | ||||||
| @@ -789,8 +784,22 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|  |  | ||||||
|             // Draw current page indicator on exact position |             // Draw current page indicator on exact position | ||||||
|             val currentIndicatorRangeStart = pageIndicatorsStart + lastPage * pageIndicatorStep |             val currentIndicatorRangeStart = pageIndicatorsStart + lastPage * pageIndicatorStep | ||||||
|             val currentIndicatorRangeEnd = pageIndicatorsStart + currentPage * pageIndicatorStep |             val indicatorEndPage = if (abs(pageChangeSwipedPercentage) > 0f) { | ||||||
|             val currentIndicatorPosition = MathUtils.lerp(currentIndicatorRangeStart, currentIndicatorRangeEnd, 1 - pageChangeAnimLeftPercentage) |                 if (pageChangeSwipedPercentage > 0f) { | ||||||
|  |                     currentPage - 1 | ||||||
|  |                 } else { | ||||||
|  |                     currentPage + 1 | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 currentPage | ||||||
|  |             } | ||||||
|  |             val currentIndicatorRangeEnd = pageIndicatorsStart + indicatorEndPage * pageIndicatorStep | ||||||
|  |             val lerpAmount = if (pageChangeAnimLeftPercentage > 0f) { | ||||||
|  |                 1 - pageChangeAnimLeftPercentage | ||||||
|  |             } else { | ||||||
|  |                 abs(pageChangeSwipedPercentage) | ||||||
|  |             } | ||||||
|  |             val currentIndicatorPosition = MathUtils.lerp(currentIndicatorRangeStart, currentIndicatorRangeEnd, lerpAmount) | ||||||
|             if (pageChangeIndicatorsAlpha != 0f) { |             if (pageChangeIndicatorsAlpha != 0f) { | ||||||
|                 currentPageIndicatorPaint.alpha = (pageChangeIndicatorsAlpha * 255.0f).toInt() |                 currentPageIndicatorPaint.alpha = (pageChangeIndicatorsAlpha * 255.0f).toInt() | ||||||
|             } else { |             } else { | ||||||
| @@ -1087,11 +1096,13 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|     private fun handlePageChange(redraw: Boolean = false) { |     private fun handlePageChange(redraw: Boolean = false) { | ||||||
|         pageChangeEnabled = false |         pageChangeEnabled = false | ||||||
|         pageChangeIndicatorsAlpha = 0f |         pageChangeIndicatorsAlpha = 0f | ||||||
|  |         val startingAt = 1 - abs(pageChangeSwipedPercentage) | ||||||
|  |         pageChangeSwipedPercentage = 0f | ||||||
|         removeCallbacks(startFadingIndicators) |         removeCallbacks(startFadingIndicators) | ||||||
|         if (redraw) { |         if (redraw) { | ||||||
|             redrawGrid() |             redrawGrid() | ||||||
|         } |         } | ||||||
|         ValueAnimator.ofFloat(1f, 0f) |         ValueAnimator.ofFloat(startingAt, 0f) | ||||||
|             .apply { |             .apply { | ||||||
|                 addUpdateListener { |                 addUpdateListener { | ||||||
|                     pageChangeAnimLeftPercentage = it.animatedValue as Float |                     pageChangeAnimLeftPercentage = it.animatedValue as Float | ||||||
| @@ -1112,6 +1123,63 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel | |||||||
|             } |             } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private fun isBetweenPages() = | ||||||
|  |         (pageChangeSwipedPercentage > 0f && pageChangeSwipedPercentage < 1f) || (pageChangeAnimLeftPercentage > 0f && pageChangeAnimLeftPercentage < 1f) | ||||||
|  |  | ||||||
|  |     private fun getXFactorForCurrentPage(): Float { | ||||||
|  |         return if (abs(pageChangeSwipedPercentage) > 0f) { | ||||||
|  |             pageChangeSwipedPercentage | ||||||
|  |         } else { | ||||||
|  |             if (currentPage > lastPage) { | ||||||
|  |                 pageChangeAnimLeftPercentage | ||||||
|  |             } else { | ||||||
|  |                 -pageChangeAnimLeftPercentage | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private fun getXFactorForLastPage(): Float { | ||||||
|  |         return if (abs(pageChangeSwipedPercentage) > 0f) { | ||||||
|  |             (1 - abs(pageChangeSwipedPercentage)) * -sign(pageChangeSwipedPercentage) | ||||||
|  |         } else { | ||||||
|  |             if (currentPage > lastPage) { | ||||||
|  |                 pageChangeAnimLeftPercentage - 1 | ||||||
|  |             } else { | ||||||
|  |                 1 - pageChangeAnimLeftPercentage | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun setSwipeMovement(diffX: Float) { | ||||||
|  |         if (!pageChangeEnabled) { | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (currentPage < getMaxPage() && diffX > 0f || currentPage > 0 && diffX < 0f) { | ||||||
|  |             pageChangeSwipedPercentage = (-diffX / width.toFloat()).coerceIn(-1f, 1f) | ||||||
|  |             redrawGrid() | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun finalizeSwipe() { | ||||||
|  |         if (abs(pageChangeSwipedPercentage) > 0.5f) { | ||||||
|  |             lastPage = currentPage | ||||||
|  |             currentPage = if (pageChangeSwipedPercentage > 0f) { | ||||||
|  |                 currentPage - 1 | ||||||
|  |             } else { | ||||||
|  |                 currentPage + 1 | ||||||
|  |             } | ||||||
|  |             handlePageChange(true) | ||||||
|  |         } else { | ||||||
|  |             lastPage = if (pageChangeSwipedPercentage > 0f) { | ||||||
|  |                 currentPage - 1 | ||||||
|  |             } else { | ||||||
|  |                 currentPage + 1 | ||||||
|  |             } | ||||||
|  |             handlePageChange(true) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     companion object { |     companion object { | ||||||
|         private const val PAGE_CHANGE_HOLD_THRESHOLD = 500L |         private const val PAGE_CHANGE_HOLD_THRESHOLD = 500L | ||||||
|         private const val PAGE_INDICATORS_FADE_DELAY = PAGE_CHANGE_HOLD_THRESHOLD + 300L |         private const val PAGE_INDICATORS_FADE_DELAY = PAGE_CHANGE_HOLD_THRESHOLD + 300L | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user