This repository has been archived by the owner on Nov 1, 2022. It is now read-only.
/
EngineViewBrowserToolbarBehavior.kt
88 lines (78 loc) · 3.64 KB
/
EngineViewBrowserToolbarBehavior.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package mozilla.components.feature.session.behavior
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.coordinatorlayout.widget.CoordinatorLayout
import mozilla.components.concept.engine.EngineView
import mozilla.components.support.ktx.android.view.findViewInHierarchy
/**
* A [CoordinatorLayout.Behavior] implementation that allows the [EngineView] to automatically
* size itself in relation to the Y translation of the [BrowserToolbar].
*
* This is useful for dynamic [BrowserToolbar]s ensuring the web content is displayed immediately
* below / above the toolbar even when that is animated.
*
* @param context [Context] used for various Android interactions
* @param attrs XML set attributes configuring this
* @param engineViewParent [NestedScrollingChild] parent of the [EngineView]
* @param toolbarHeight size of [BrowserToolbar] when it is placed above the [EngineView]
* @param whether the [BrowserToolbar] is placed above or below the [EngineView]
*/
class EngineViewBrowserToolbarBehavior(
context: Context?,
attrs: AttributeSet?,
engineViewParent: View,
toolbarHeight: Int,
toolbarPosition: ToolbarPosition
) : CoordinatorLayout.Behavior<View>(context, attrs) {
private val engineView = engineViewParent.findViewInHierarchy { it is EngineView } as EngineView?
private var toolbarChangedAction: (Float) -> Unit?
private val bottomToolbarChangedAction = { newToolbarTranslationY: Float ->
engineView?.setVerticalClipping(-newToolbarTranslationY.toInt())
}
private val topToolbarChangedAction = { newToolbarTranslationY: Float ->
// the top toolbar is translated upwards when collapsing-> all values received are 0 or negative
engineView?.let {
it.setVerticalClipping(newToolbarTranslationY.toInt())
// Need to add the toolbarHeight to effectively place the engineView below the toolbar.
engineViewParent.translationY = newToolbarTranslationY + toolbarHeight
}
}
init {
toolbarChangedAction = if (toolbarPosition == ToolbarPosition.TOP) {
topToolbarChangedAction
} else {
bottomToolbarChangedAction
}
}
@SuppressLint("LogUsage")
override fun layoutDependsOn(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
// This package does not have access to "BrowserToolbar" ... so we are just checking the class name here since
// we actually do not need anything from that class - we only need to identify the instance.
// Right now we do not have a component that has access to (concept/browser-toolbar and concept-engine).
// Creating one just for this behavior is too excessive.
if (dependency::class.java.simpleName == "BrowserToolbar") {
return true
}
return super.layoutDependsOn(parent, child, dependency)
}
/**
* Apply vertical clipping to [EngineView]. This requires [EngineViewBrowserToolbarBehavior] to be set
* in/on the [EngineView] or its parent. Must be a direct descending child of [CoordinatorLayout].
*/
override fun onDependentViewChanged(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
toolbarChangedAction.invoke(dependency.translationY)
return true
}
}
/**
* Where the toolbar is placed on the screen.
*/
enum class ToolbarPosition {
TOP,
BOTTOM
}