Merge "a11y local actions - fling bubble stack to corners" into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
2d1d3248fd
@@ -103,6 +103,12 @@
|
|||||||
<item type="id" name="action_snooze_assistant_suggestion_1"/>
|
<item type="id" name="action_snooze_assistant_suggestion_1"/>
|
||||||
<item type="id" name="action_snooze"/>
|
<item type="id" name="action_snooze"/>
|
||||||
|
|
||||||
|
<!-- Accessibility actions for bubbles. -->
|
||||||
|
<item type="id" name="action_move_top_left"/>
|
||||||
|
<item type="id" name="action_move_top_right"/>
|
||||||
|
<item type="id" name="action_move_bottom_left"/>
|
||||||
|
<item type="id" name="action_move_bottom_right"/>
|
||||||
|
|
||||||
<!-- For StatusIconContainer to tag its icon views -->
|
<!-- For StatusIconContainer to tag its icon views -->
|
||||||
<item type="id" name="status_bar_view_state_tag" />
|
<item type="id" name="status_bar_view_state_tag" />
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import android.view.ViewTreeObserver;
|
|||||||
import android.view.WindowInsets;
|
import android.view.WindowInsets;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.accessibility.AccessibilityNodeInfo;
|
import android.view.accessibility.AccessibilityNodeInfo;
|
||||||
|
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
|
||||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -391,11 +392,34 @@ public class BubbleStackView extends FrameLayout {
|
|||||||
@Override
|
@Override
|
||||||
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
|
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
|
||||||
super.onInitializeAccessibilityNodeInfoInternal(info);
|
super.onInitializeAccessibilityNodeInfoInternal(info);
|
||||||
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
|
|
||||||
|
// Custom actions.
|
||||||
|
AccessibilityAction moveTopLeft = new AccessibilityAction(R.id.action_move_top_left,
|
||||||
|
getContext().getResources()
|
||||||
|
.getString(R.string.bubble_accessibility_action_move_top_left));
|
||||||
|
info.addAction(moveTopLeft);
|
||||||
|
|
||||||
|
AccessibilityAction moveTopRight = new AccessibilityAction(R.id.action_move_top_right,
|
||||||
|
getContext().getResources()
|
||||||
|
.getString(R.string.bubble_accessibility_action_move_top_right));
|
||||||
|
info.addAction(moveTopRight);
|
||||||
|
|
||||||
|
AccessibilityAction moveBottomLeft = new AccessibilityAction(R.id.action_move_bottom_left,
|
||||||
|
getContext().getResources()
|
||||||
|
.getString(R.string.bubble_accessibility_action_move_bottom_left));
|
||||||
|
info.addAction(moveBottomLeft);
|
||||||
|
|
||||||
|
AccessibilityAction moveBottomRight = new AccessibilityAction(R.id.action_move_bottom_right,
|
||||||
|
getContext().getResources()
|
||||||
|
.getString(R.string.bubble_accessibility_action_move_bottom_right));
|
||||||
|
info.addAction(moveBottomRight);
|
||||||
|
|
||||||
|
// Default actions.
|
||||||
|
info.addAction(AccessibilityAction.ACTION_DISMISS);
|
||||||
if (mIsExpanded) {
|
if (mIsExpanded) {
|
||||||
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE);
|
info.addAction(AccessibilityAction.ACTION_COLLAPSE);
|
||||||
} else {
|
} else {
|
||||||
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
|
info.addAction(AccessibilityAction.ACTION_EXPAND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,16 +428,30 @@ public class BubbleStackView extends FrameLayout {
|
|||||||
if (super.performAccessibilityActionInternal(action, arguments)) {
|
if (super.performAccessibilityActionInternal(action, arguments)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
switch (action) {
|
final RectF stackBounds = mStackAnimationController.getAllowableStackPositionRegion();
|
||||||
case AccessibilityNodeInfo.ACTION_DISMISS:
|
|
||||||
|
// R constants are not final so we cannot use switch-case here.
|
||||||
|
if (action == AccessibilityNodeInfo.ACTION_DISMISS) {
|
||||||
mBubbleData.dismissAll(BubbleController.DISMISS_ACCESSIBILITY_ACTION);
|
mBubbleData.dismissAll(BubbleController.DISMISS_ACCESSIBILITY_ACTION);
|
||||||
return true;
|
return true;
|
||||||
case AccessibilityNodeInfo.ACTION_COLLAPSE:
|
} else if (action == AccessibilityNodeInfo.ACTION_COLLAPSE) {
|
||||||
mBubbleData.setExpanded(false);
|
mBubbleData.setExpanded(false);
|
||||||
return true;
|
return true;
|
||||||
case AccessibilityNodeInfo.ACTION_EXPAND:
|
} else if (action == AccessibilityNodeInfo.ACTION_EXPAND) {
|
||||||
mBubbleData.setExpanded(true);
|
mBubbleData.setExpanded(true);
|
||||||
return true;
|
return true;
|
||||||
|
} else if (action == R.id.action_move_top_left) {
|
||||||
|
mStackAnimationController.springStack(stackBounds.left, stackBounds.top);
|
||||||
|
return true;
|
||||||
|
} else if (action == R.id.action_move_top_right) {
|
||||||
|
mStackAnimationController.springStack(stackBounds.right, stackBounds.top);
|
||||||
|
return true;
|
||||||
|
} else if (action == R.id.action_move_bottom_left) {
|
||||||
|
mStackAnimationController.springStack(stackBounds.left, stackBounds.bottom);
|
||||||
|
return true;
|
||||||
|
} else if (action == R.id.action_move_bottom_right) {
|
||||||
|
mStackAnimationController.springStack(stackBounds.right, stackBounds.bottom);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,11 +175,33 @@ public class StackAnimationController extends
|
|||||||
|
|
||||||
/** Whether the stack is on the left side of the screen. */
|
/** Whether the stack is on the left side of the screen. */
|
||||||
public boolean isStackOnLeftSide() {
|
public boolean isStackOnLeftSide() {
|
||||||
if (mLayout != null) {
|
if (mLayout == null) {
|
||||||
return mStackPosition.x - mIndividualBubbleSize / 2 < mLayout.getWidth() / 2;
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
float stackCenter = mStackPosition.x + mIndividualBubbleSize / 2;
|
||||||
|
float screenCenter = mLayout.getWidth() / 2;
|
||||||
|
return stackCenter < screenCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fling stack to given corner, within allowable screen bounds.
|
||||||
|
* Note that we need new SpringForce instances per animation despite identical configs because
|
||||||
|
* SpringAnimation uses SpringForce's internal (changing) velocity while the animation runs.
|
||||||
|
*/
|
||||||
|
public void springStack(float destinationX, float destinationY) {
|
||||||
|
springFirstBubbleWithStackFollowing(DynamicAnimation.TRANSLATION_X,
|
||||||
|
new SpringForce()
|
||||||
|
.setStiffness(SPRING_AFTER_FLING_STIFFNESS)
|
||||||
|
.setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO),
|
||||||
|
0 /* startXVelocity */,
|
||||||
|
destinationX);
|
||||||
|
|
||||||
|
springFirstBubbleWithStackFollowing(DynamicAnimation.TRANSLATION_Y,
|
||||||
|
new SpringForce()
|
||||||
|
.setStiffness(SPRING_AFTER_FLING_STIFFNESS)
|
||||||
|
.setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO),
|
||||||
|
0 /* startYVelocity */,
|
||||||
|
destinationY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -352,6 +374,7 @@ public class StackAnimationController extends
|
|||||||
float destinationY = Float.MIN_VALUE;
|
float destinationY = Float.MIN_VALUE;
|
||||||
|
|
||||||
if (imeVisible) {
|
if (imeVisible) {
|
||||||
|
// Stack is lower than it should be and overlaps the now-visible IME.
|
||||||
if (mStackPosition.y > maxBubbleY && mPreImeY == Float.MIN_VALUE) {
|
if (mStackPosition.y > maxBubbleY && mPreImeY == Float.MIN_VALUE) {
|
||||||
mPreImeY = mStackPosition.y;
|
mPreImeY = mStackPosition.y;
|
||||||
destinationY = maxBubbleY;
|
destinationY = maxBubbleY;
|
||||||
|
|||||||
Reference in New Issue
Block a user