fix(calls): bound + unclip the answer drag — disc rides a clamped track (trackMax/lateralMax), clipChildren=false up the chain, halo follows; no clip-square, no full-screen runaway
This commit is contained in:
parent
fe32bed081
commit
628618aafe
2 changed files with 35 additions and 10 deletions
|
|
@ -250,6 +250,13 @@ public class IncomingCallActivity extends Activity {
|
|||
// made "slide to answer" indistinguishable from a twitch. dp(88) ≈ a disc
|
||||
// diameter of climb. needsDevice: tune one-handed reach on a tall phone.
|
||||
final float commitDistance = Math.max(touchSlop * 4f, dp(88f));
|
||||
// The disc rides a BOUNDED track. trackMax caps how far up it can follow the
|
||||
// finger (progress p already saturates at the commit point, so chasing the
|
||||
// finger further just slides the disc off into empty screen); lateralMax
|
||||
// keeps the slide on its vertical rail. Without these the disc trails the
|
||||
// finger 1:1 across the whole screen.
|
||||
final float trackMax = commitDistance;
|
||||
final float lateralMax = dp(24f);
|
||||
return new View.OnTouchListener() {
|
||||
private float downX;
|
||||
private float downY;
|
||||
|
|
@ -279,10 +286,11 @@ public class IncomingCallActivity extends Activity {
|
|||
if (dragging) {
|
||||
float up = -dy; // upward = positive progress
|
||||
float p = (float) Math.min(1.0, Math.max(0.0, up / commitDistance));
|
||||
// Track the finger UP its rail: a little lateral follow,
|
||||
// but the disc never travels downward (down = no commit).
|
||||
disc.setTranslationX(0.15f * dx);
|
||||
disc.setTranslationY(Math.min(0f, dy));
|
||||
// Follow the finger UP its rail, clamped to the track: the
|
||||
// disc never travels downward and never past trackMax, with
|
||||
// only a small clamped lateral give.
|
||||
disc.setTranslationX(Math.max(-lateralMax, Math.min(lateralMax, 0.15f * dx)));
|
||||
disc.setTranslationY(-Math.min(Math.max(up, 0f), trackMax));
|
||||
applyProgressVisuals(disc, glow, decline, p);
|
||||
hapticLadder(disc, p);
|
||||
}
|
||||
|
|
@ -327,6 +335,10 @@ public class IncomingCallActivity extends Activity {
|
|||
float gs = 0.58f + 0.42f * p; // peak 1.0 (the 124dp glow already covers the disc)
|
||||
glow.setScaleX(gs);
|
||||
glow.setScaleY(gs);
|
||||
// Keep the halo glued behind the moving disc — otherwise it blooms at the
|
||||
// rest position while the disc slides up and away, decoupling the two.
|
||||
glow.setTranslationX(disc.getTranslationX());
|
||||
glow.setTranslationY(disc.getTranslationY());
|
||||
}
|
||||
if (decline != null) {
|
||||
// The screen "takes a side": the decline disc recedes as answer climbs.
|
||||
|
|
@ -381,6 +393,7 @@ public class IncomingCallActivity extends Activity {
|
|||
}
|
||||
if (glow != null) {
|
||||
glow.animate().alpha(0f).scaleX(0.58f).scaleY(0.58f)
|
||||
.translationX(0f).translationY(0f)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.setDuration(dur + 60)
|
||||
.start();
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@
|
|||
android:gravity="center_horizontal"
|
||||
android:fitsSystemWindows="true"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingEnd="24dp">
|
||||
android:paddingEnd="24dp"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
|
|
@ -19,10 +21,12 @@
|
|||
android:layout_weight="1.1" />
|
||||
|
||||
<!-- Avatar disc (caller initial, set in code) behind a breathing halo. Sized
|
||||
124dp to match the over-lock hero avatar so answer-from-lock doesn't pop. -->
|
||||
124dp to match the over-lock hero avatar so answer-from-lock doesn't pop.
|
||||
clipChildren=false so the pulsing halo can bloom past the 160dp box. -->
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false">
|
||||
|
||||
<View
|
||||
android:id="@+id/call_avatar_halo"
|
||||
|
|
@ -72,12 +76,18 @@
|
|||
android:layout_height="0dp"
|
||||
android:layout_weight="2" />
|
||||
|
||||
<!-- clipChildren/clipToPadding=false so the answer disc can slide UP out of the
|
||||
action row (and the column + FrameLayout below) without being clipped at a
|
||||
container edge — otherwise the dragged disc vanishes behind the 124dp glow
|
||||
box. The whole ancestor chain to the root must opt out. -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="56dp"
|
||||
android:weightSum="2">
|
||||
android:weightSum="2"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<!-- Decline -->
|
||||
<LinearLayout
|
||||
|
|
@ -127,7 +137,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
android:gravity="center"
|
||||
android:clipChildren="false">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/answer_hint"
|
||||
|
|
@ -140,7 +151,8 @@
|
|||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false">
|
||||
|
||||
<View
|
||||
android:id="@+id/answer_glow"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue