Base: Predictive Back, add support for large screens when swiping
The back progress is linear on smartphones or devices with a screen width less than the `linearDistance`, which can be configured in the resources. The `deltaX` is the distance from the current point to the point where the back started.
The progress value is calculated as follows:
- If the `maxDistance` (screen width) is less than the `linearDistance`, the progress will be completely linear (with target `maxDistance`), so we will have: `progress = deltaX / maxDistance`
- If the `maxDistance` is greater than the `linearDistance`, the progress will be linear for the first part (up to `linearDistance`) and then go slowly to 1f.
- If `deltaX` is less than `linearDistance`, we are in the linear part, and the target will no longer be the `maxDistance` but the sum of `linearDistance` and `nonLinearDistance * nonLinearFactor` (a distance between `linearDistance` and `maxDistance`).
- If `deltaX` is greater than `linearDistance`, we are in the non-linear part, and the target will move linearly towards `maxDistance` so as to have a smooth curve towards the end of the screen.
The resources used are:
- `linearDistance` uses the `resource navigation_edge_action_progress_threshold` (with value 412dp)
- `nonLinearFactor` uses the `resource navigation_edge_action_progress_non_linear_factor` (with value 0.2)
screen screen screen
width width width
|——————| |————————————| |————————————————————|
A B A B C A
1 +——————+—————+ 1 +————————————+ 1 +————————————+———————+
| / | | —/| | | —————/|
| / | | —/ | | ——/ |
| / | | —/ | | ——/ | |
| / | | —/ | | ——/ | |
| / | | —/ | | ——/ | |
|/ | |—/ | |—/ | |
0 +————————————+ 0 +————————————+ 0 +————————————+———————+
B B B
Three devices with different widths (smaller, equal, and wider) relative to the progress
threshold are shown in the graphs.
- `A` is the width of the screen
- `B` is the progress threshold (horizontal swipe distance where progress is linear)
- `C` equals `B + (A - B) * nonLinearFactor`
If `A` is less than or equal to `B`, `progress` for the swipe distance between:
- `[0, A]` will scale linearly between `[0, 1]`.
If A is greater than B, `progress` for swipe distance between:
- `[0, B]` will scale linearly between `[0, B / C]`
- `(B, A]` will scale non-linearly and reach 1.
Test: atest TouchTrackerTest
Bug: 271508045
Change-Id: Ib96fea37ba1af091cbe3406754f3a35ccf5557f7
7 files changed