Smooth mode switching - #679
Conversation
25fd41a to
db39c2d
Compare
| val centers = (0 until tabParent.childCount).map { | ||
| val tabView = tabParent.getChildAt(it) | ||
| tabView.left + tabView.width / 2 - width / 2 | ||
| } |
There was a problem hiding this comment.
Could this use the children extension?
| val centers = (0 until tabParent.childCount).map { | |
| val tabView = tabParent.getChildAt(it) | |
| tabView.left + tabView.width / 2 - width / 2 | |
| } | |
| val centers = tabParent.children.take(tabCount).map { | |
| it.left + it.width / 2 - width / 2 | |
| }.toList() |
Separately, would it be worth iterating tabCount instead of childCount? Everything downstream compares the result against tabCount.
| val target = tabCenters.getOrNull(tab.position) | ||
| val duration = if (target == null) 0L else settleDuration(abs(target - scrollX)) | ||
|
|
||
| // snapPoints is empty until the first layout pass, and goes stale when the tab set is | ||
| // rebuilt, so an index taken from it may no longer name a tab. | ||
| if (snapPoints.isEmpty() || snapPoints.last() == 0) { | ||
| if (target == null || duration == 0L || !ValueAnimator.areAnimatorsEnabled()) { | ||
| target?.let { scrollTo(it, 0) } | ||
| onSettled?.run() | ||
| return | ||
| } |
There was a problem hiding this comment.
Small thing: target == null gets tested twice.
| val target = tabCenters.getOrNull(tab.position) | |
| val duration = if (target == null) 0L else settleDuration(abs(target - scrollX)) | |
| // snapPoints is empty until the first layout pass, and goes stale when the tab set is | |
| // rebuilt, so an index taken from it may no longer name a tab. | |
| if (snapPoints.isEmpty() || snapPoints.last() == 0) { | |
| if (target == null || duration == 0L || !ValueAnimator.areAnimatorsEnabled()) { | |
| target?.let { scrollTo(it, 0) } | |
| onSettled?.run() | |
| return | |
| } | |
| val target = tabCenters.getOrNull(tab.position) ?: run { | |
| onSettled?.run() | |
| return | |
| } | |
| val duration = settleDuration(abs(target - scrollX)) | |
| if (duration == 0L || !ValueAnimator.areAnimatorsEnabled()) { | |
| scrollTo(target, 0) | |
| onSettled?.run() | |
| return | |
| } |
| val selectedWidth = selectedChild.width | ||
|
|
||
| return selectedChild.left + selectedWidth - width / 2 | ||
| private fun fractionalTabPosition(x: Int): Float { |
There was a problem hiding this comment.
nit: tabCenters.lastIndex in both spots reads a little better, and the empty case then falls out on its own.
| // is already visible and to dismiss it if the permission gets granted. | ||
| private var cameraPermissionDialog: AlertDialog? = null | ||
| private var audioPermissionDialog: AlertDialog? = null | ||
| @Volatile |
| if (frameCopyPending || hasFreshPrefetch()) return | ||
| if (previewView.width == 0 || previewView.height == 0) return | ||
|
|
||
| val surfaceView = previewView.getChildAt(0) as? SurfaceView ?: return |
sdsantos
left a comment
There was a problem hiding this comment.
Found a bug when changing tabs. If you click on a tab to change, and they quickly tap back on the tab you were before, the camera surface is stuck on the blurred preview and never shows the live camera, until you click on another tab.
camera_switch_stuck.mp4
|
|
||
| override fun onScrollChanged(x: Int, y: Int, oldX: Int, oldY: Int) { | ||
| super.onScrollChanged(x, y, oldX, oldY) | ||
| fun goToTab(tab: Tab, onSettled: Runnable? = null) { |
There was a problem hiding this comment.
Looks like nothing is using that onSettled.
No description provided.