When swiping notifications it doesn't clip early anymore
Previously notifications started to clip before reaching the edge. We're now changinging the flags to dismiss with translation instead of clipping the contents. This is change 1/2 as the notification container should clip the notification now, which is especially noticeable in split shade. Bug: 181887261 Test: dismiss notifications, visually observe no clipping Change-Id: I003b1486ce64dd127a90ca2d9f982230eba79f60
This commit is contained in:
@@ -396,10 +396,6 @@
|
||||
<!-- Whether or not the notifications should always fade as they are dismissed. -->
|
||||
<bool name="config_fadeNotificationsOnDismiss">false</bool>
|
||||
|
||||
<!-- Whether or not the parent of the notification row itself is being translated when swiped or
|
||||
its children views. If true, then the contents are translated and vice versa. -->
|
||||
<bool name="config_translateNotificationContentsOnSwipe">true</bool>
|
||||
|
||||
<!-- Whether or not the fade on the notification is based on the amount that it has been swiped
|
||||
off-screen. -->
|
||||
<bool name="config_fadeDependingOnAmountSwiped">false</bool>
|
||||
|
||||
@@ -391,9 +391,9 @@ public class SwipeHelper implements Gefingerpoken {
|
||||
boolean animateLeft = (Math.abs(velocity) > getEscapeVelocity() && velocity < 0) ||
|
||||
(getTranslation(animView) < 0 && !isDismissAll);
|
||||
if (animateLeft || animateLeftForRtl || animateUpForMenu) {
|
||||
newPos = -getSize(animView);
|
||||
newPos = -getTotalTranslationLength(animView);
|
||||
} else {
|
||||
newPos = getSize(animView);
|
||||
newPos = getTotalTranslationLength(animView);
|
||||
}
|
||||
long duration;
|
||||
if (fixedDuration == 0) {
|
||||
@@ -469,6 +469,15 @@ public class SwipeHelper implements Gefingerpoken {
|
||||
anim.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total translation length where we want to swipe to when dismissing the view. By
|
||||
* default this is the size of the view, but can also be larger.
|
||||
* @param animView the view to ask about
|
||||
*/
|
||||
protected float getTotalTranslationLength(View animView) {
|
||||
return getSize(animView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the dismiss animation.
|
||||
*/
|
||||
|
||||
@@ -71,11 +71,11 @@ public final class NotificationClicker implements View.OnClickListener {
|
||||
// Check if the notification is displaying the menu, if so slide notification back
|
||||
if (isMenuVisible(row)) {
|
||||
mLogger.logMenuVisible(entry);
|
||||
row.animateTranslateNotification(0);
|
||||
row.animateResetTranslation();
|
||||
return;
|
||||
} else if (row.isChildInGroup() && isMenuVisible(row.getNotificationParent())) {
|
||||
mLogger.logParentMenuVisible(entry);
|
||||
row.getNotificationParent().animateTranslateNotification(0);
|
||||
row.getNotificationParent().animateResetTranslation();
|
||||
return;
|
||||
} else if (row.isSummaryWithChildren() && row.areChildrenExpanded()) {
|
||||
// We never want to open the app directly if the user clicks in between
|
||||
|
||||
@@ -874,7 +874,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
@Override
|
||||
protected boolean handleSlideBack() {
|
||||
if (mMenuRow != null && mMenuRow.isMenuVisible()) {
|
||||
animateTranslateNotification(0 /* targetLeft */);
|
||||
animateResetTranslation();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -1711,21 +1711,17 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
mChildrenContainer.setContainingNotification(ExpandableNotificationRow.this);
|
||||
mChildrenContainer.onNotificationUpdated();
|
||||
|
||||
if (mShouldTranslateContents) {
|
||||
mTranslateableViews.add(mChildrenContainer);
|
||||
}
|
||||
mTranslateableViews.add(mChildrenContainer);
|
||||
});
|
||||
|
||||
if (mShouldTranslateContents) {
|
||||
// Add the views that we translate to reveal the menu
|
||||
mTranslateableViews = new ArrayList<>();
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
mTranslateableViews.add(getChildAt(i));
|
||||
}
|
||||
// Remove views that don't translate
|
||||
mTranslateableViews.remove(mChildrenContainerStub);
|
||||
mTranslateableViews.remove(mGutsStub);
|
||||
// Add the views that we translate to reveal the menu
|
||||
mTranslateableViews = new ArrayList<>();
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
mTranslateableViews.add(getChildAt(i));
|
||||
}
|
||||
// Remove views that don't translate
|
||||
mTranslateableViews.remove(mChildrenContainerStub);
|
||||
mTranslateableViews.remove(mGutsStub);
|
||||
}
|
||||
|
||||
private void doLongClickCallback() {
|
||||
@@ -1803,7 +1799,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
mTranslateAnim.cancel();
|
||||
}
|
||||
|
||||
if (!mShouldTranslateContents) {
|
||||
if (mDismissUsingRowTranslationX) {
|
||||
setTranslationX(0);
|
||||
} else if (mTranslateableViews != null) {
|
||||
for (int i = 0; i < mTranslateableViews.size(); i++) {
|
||||
@@ -1865,23 +1861,47 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
return mPrivateLayout.getActiveRemoteInputText();
|
||||
}
|
||||
|
||||
public void animateTranslateNotification(final float leftTarget) {
|
||||
/**
|
||||
* Reset the translation with an animation.
|
||||
*/
|
||||
public void animateResetTranslation() {
|
||||
if (mTranslateAnim != null) {
|
||||
mTranslateAnim.cancel();
|
||||
}
|
||||
mTranslateAnim = getTranslateViewAnimator(leftTarget, null /* updateListener */);
|
||||
mTranslateAnim = getTranslateViewAnimator(0, null /* updateListener */);
|
||||
if (mTranslateAnim != null) {
|
||||
mTranslateAnim.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dismiss behavior of the view.
|
||||
* @param usingRowTranslationX {@code true} if the view should translate using regular
|
||||
* translationX, otherwise the contents will be
|
||||
* translated.
|
||||
*/
|
||||
@Override
|
||||
public void setDismissUsingRowTranslationX(boolean usingRowTranslationX) {
|
||||
if (usingRowTranslationX != mDismissUsingRowTranslationX) {
|
||||
// In case we were already transitioning, let's switch over!
|
||||
float previousTranslation = getTranslation();
|
||||
if (previousTranslation != 0) {
|
||||
setTranslation(0);
|
||||
}
|
||||
super.setDismissUsingRowTranslationX(usingRowTranslationX);
|
||||
if (previousTranslation != 0) {
|
||||
setTranslation(previousTranslation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTranslation(float translationX) {
|
||||
invalidate();
|
||||
if (isBlockingHelperShowingAndTranslationFinished()) {
|
||||
mGuts.setTranslationX(translationX);
|
||||
return;
|
||||
} else if (!mShouldTranslateContents) {
|
||||
} else if (mDismissUsingRowTranslationX) {
|
||||
setTranslationX(translationX);
|
||||
} else if (mTranslateableViews != null) {
|
||||
// Translate the group of views
|
||||
@@ -1905,7 +1925,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
|
||||
@Override
|
||||
public float getTranslation() {
|
||||
if (!mShouldTranslateContents) {
|
||||
if (mDismissUsingRowTranslationX) {
|
||||
return getTranslationX();
|
||||
}
|
||||
|
||||
@@ -2896,7 +2916,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
float y = event.getY();
|
||||
NotificationViewWrapper wrapper = getVisibleNotificationViewWrapper();
|
||||
NotificationHeaderView header = wrapper == null ? null : wrapper.getNotificationHeader();
|
||||
if (header != null && header.isInTouchRect(x - getTranslation(), y)) {
|
||||
// the extra translation only needs to be added, if we're translating the notification
|
||||
// contents, otherwise the motionEvent is already at the right place due to the
|
||||
// touch event system.
|
||||
float translation = !mDismissUsingRowTranslationX ? getTranslation() : 0;
|
||||
if (header != null && header.isInTouchRect(x - translation, y)) {
|
||||
return true;
|
||||
}
|
||||
if ((!mIsSummaryWithChildren || shouldShowPublic())
|
||||
|
||||
@@ -71,10 +71,10 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
||||
private int mBackgroundTop;
|
||||
|
||||
/**
|
||||
* {@code true} if the children views of the {@link ExpandableOutlineView} are translated when
|
||||
* {@code false} if the children views of the {@link ExpandableOutlineView} are translated when
|
||||
* it is moved. Otherwise, the translation is set on the {@code ExpandableOutlineView} itself.
|
||||
*/
|
||||
protected boolean mShouldTranslateContents;
|
||||
protected boolean mDismissUsingRowTranslationX = true;
|
||||
private float[] mTmpCornerRadii = new float[8];
|
||||
|
||||
private final ViewOutlineProvider mProvider = new ViewOutlineProvider() {
|
||||
@@ -82,7 +82,8 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
||||
public void getOutline(View view, Outline outline) {
|
||||
if (!mCustomOutline && getCurrentTopRoundness() == 0.0f
|
||||
&& getCurrentBottomRoundness() == 0.0f && !mAlwaysRoundBothCorners) {
|
||||
int translation = mShouldTranslateContents ? (int) getTranslation() : 0;
|
||||
// Only when translating just the contents, does the outline need to be shifted.
|
||||
int translation = !mDismissUsingRowTranslationX ? (int) getTranslation() : 0;
|
||||
int left = Math.max(translation, 0);
|
||||
int top = mClipTopAmount + mBackgroundTop;
|
||||
int right = getWidth() + Math.min(translation, 0);
|
||||
@@ -107,7 +108,9 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
||||
float topRoundness = mAlwaysRoundBothCorners
|
||||
? mOutlineRadius : getCurrentBackgroundRadiusTop();
|
||||
if (!mCustomOutline) {
|
||||
int translation = mShouldTranslateContents && !ignoreTranslation
|
||||
// The outline just needs to be shifted if we're translating the contents. Otherwise
|
||||
// it's already in the right place.
|
||||
int translation = !mDismissUsingRowTranslationX && !ignoreTranslation
|
||||
? (int) getTranslation() : 0;
|
||||
int halfExtraWidth = (int) (mExtraWidthForClipping / 2.0f);
|
||||
left = Math.max(translation, 0) - halfExtraWidth;
|
||||
@@ -196,13 +199,14 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
||||
}
|
||||
|
||||
protected boolean isClippingNeeded() {
|
||||
return mAlwaysRoundBothCorners || mCustomOutline || getTranslation() != 0 ;
|
||||
// When translating the contents instead of the overall view, we need to make sure we clip
|
||||
// rounded to the contents.
|
||||
boolean forTranslation = getTranslation() != 0 && !mDismissUsingRowTranslationX;
|
||||
return mAlwaysRoundBothCorners || mCustomOutline || forTranslation;
|
||||
}
|
||||
|
||||
private void initDimens() {
|
||||
Resources res = getResources();
|
||||
mShouldTranslateContents =
|
||||
res.getBoolean(R.bool.config_translateNotificationContentsOnSwipe);
|
||||
mOutlineRadius = res.getDimension(R.dimen.notification_shadow_radius);
|
||||
mAlwaysRoundBothCorners = res.getBoolean(R.bool.config_clipNotificationsToOutline);
|
||||
if (!mAlwaysRoundBothCorners) {
|
||||
@@ -342,9 +346,25 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dismiss behavior of the view.
|
||||
* @param usingRowTranslationX {@code true} if the view should translate using regular
|
||||
* translationX, otherwise the contents will be
|
||||
* translated.
|
||||
*/
|
||||
public void setDismissUsingRowTranslationX(boolean usingRowTranslationX) {
|
||||
mDismissUsingRowTranslationX = usingRowTranslationX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOutlineTranslation() {
|
||||
return mCustomOutline ? mOutlineRect.left : (int) getTranslation();
|
||||
if (mCustomOutline) {
|
||||
return mOutlineRect.left;
|
||||
}
|
||||
if (mDismissUsingRowTranslationX) {
|
||||
return 0;
|
||||
}
|
||||
return (int) getTranslation();
|
||||
}
|
||||
|
||||
public void updateOutline() {
|
||||
|
||||
@@ -475,6 +475,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
* Are we launching a notification right now
|
||||
*/
|
||||
private boolean mLaunchingNotification;
|
||||
|
||||
/**
|
||||
* Do notifications dismiss with normal transitioning
|
||||
*/
|
||||
private boolean mDismissUsingRowTranslationX = true;
|
||||
private NotificationEntry mTopHeadsUpEntry;
|
||||
private long mNumHeadsUp;
|
||||
private NotificationStackScrollLayoutController.TouchHandler mTouchHandler;
|
||||
@@ -528,7 +533,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
mSectionsManager = notificationSectionsManager;
|
||||
mFeatureFlags = featureFlags;
|
||||
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
|
||||
mShouldUseSplitNotificationShade = shouldUseSplitNotificationShade(mFeatureFlags, res);
|
||||
updateSplitNotificationShade();
|
||||
mSectionsManager.initialize(this, LayoutInflater.from(context));
|
||||
mSections = mSectionsManager.createSectionsForBuckets();
|
||||
|
||||
@@ -1600,8 +1605,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
Resources res = getResources();
|
||||
mShouldUseSplitNotificationShade = shouldUseSplitNotificationShade(mFeatureFlags, res);
|
||||
updateUseRoundedRectClipping();
|
||||
updateSplitNotificationShade();
|
||||
mStatusBarHeight = res.getDimensionPixelOffset(R.dimen.status_bar_height);
|
||||
float densityScale = res.getDisplayMetrics().density;
|
||||
mSwipeHelper.setDensityScale(densityScale);
|
||||
@@ -2528,8 +2532,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
updateScrollStateForRemovedChild(child);
|
||||
boolean animationGenerated = generateRemoveAnimation(child);
|
||||
if (animationGenerated) {
|
||||
if (!mSwipedOutViews.contains(child)
|
||||
|| Math.abs(child.getTranslation()) != child.getWidth()) {
|
||||
if (!mSwipedOutViews.contains(child) || !isFullySwipedOut(child)) {
|
||||
container.addTransientView(child, 0);
|
||||
child.setTransientContainer(container);
|
||||
}
|
||||
@@ -2541,6 +2544,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
focusNextViewIfFocused(child);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has this view been fully swiped out such that it's not visible anymore.
|
||||
*/
|
||||
public boolean isFullySwipedOut(ExpandableView child) {
|
||||
return Math.abs(child.getTranslation()) >= Math.abs(getTotalTranslationLength(child));
|
||||
}
|
||||
|
||||
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
||||
private void focusNextViewIfFocused(View view) {
|
||||
if (view instanceof ExpandableNotificationRow) {
|
||||
@@ -2759,7 +2769,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
updateAnimationState(child);
|
||||
updateChronometerForChild(child);
|
||||
if (child instanceof ExpandableNotificationRow) {
|
||||
((ExpandableNotificationRow) child).setDismissRtl(mDismissRtl);
|
||||
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
|
||||
row.setDismissRtl(mDismissRtl);
|
||||
row.setDismissUsingRowTranslationX(mDismissUsingRowTranslationX);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3033,7 +3046,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
removedTranslation = row.getTranslationWhenRemoved();
|
||||
ignoreChildren = false;
|
||||
}
|
||||
childWasSwipedOut |= Math.abs(row.getTranslation()) == row.getWidth();
|
||||
childWasSwipedOut |= isFullySwipedOut(row);
|
||||
} else if (child instanceof MediaHeaderView) {
|
||||
childWasSwipedOut = true;
|
||||
}
|
||||
@@ -3041,11 +3054,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
Rect clipBounds = child.getClipBounds();
|
||||
childWasSwipedOut = clipBounds != null && clipBounds.height() == 0;
|
||||
|
||||
if (childWasSwipedOut && child instanceof ExpandableView) {
|
||||
if (childWasSwipedOut) {
|
||||
// Clean up any potential transient views if the child has already been swiped
|
||||
// out, as we won't be animating it further (due to its height already being
|
||||
// clipped to 0.
|
||||
ViewGroup transientContainer = ((ExpandableView) child).getTransientContainer();
|
||||
ViewGroup transientContainer = child.getTransientContainer();
|
||||
if (transientContainer != null) {
|
||||
transientContainer.removeTransientView(child);
|
||||
}
|
||||
@@ -4051,7 +4064,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
expandableView.setFakeShadowIntensity(
|
||||
diff / FakeShadowView.SHADOW_SIBLING_TRESHOLD,
|
||||
previous.getOutlineAlpha(), (int) yLocation,
|
||||
previous.getOutlineTranslation());
|
||||
(int) (previous.getOutlineTranslation() + previous.getTranslation()));
|
||||
}
|
||||
previous = expandableView;
|
||||
}
|
||||
@@ -4636,6 +4649,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
mStatusBarState = statusBarState;
|
||||
mAmbientState.setStatusBarState(statusBarState);
|
||||
updateSpeedBumpIndex();
|
||||
updateDismissBehavior();
|
||||
}
|
||||
|
||||
void onStatePostChange(boolean fromShadeLocked) {
|
||||
@@ -5224,6 +5238,32 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSplitNotificationShade() {
|
||||
boolean split = shouldUseSplitNotificationShade(mFeatureFlags, getResources());
|
||||
if (split != mShouldUseSplitNotificationShade) {
|
||||
mShouldUseSplitNotificationShade = split;
|
||||
updateDismissBehavior();
|
||||
updateUseRoundedRectClipping();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDismissBehavior() {
|
||||
// On the split keyguard, dismissing with clipping without a visual boundary looks odd,
|
||||
// so let's use the content dismiss behavior instead.
|
||||
boolean dismissUsingRowTranslationX = !mShouldUseSplitNotificationShade
|
||||
|| mStatusBarState != StatusBarState.KEYGUARD;
|
||||
if (mDismissUsingRowTranslationX != dismissUsingRowTranslationX) {
|
||||
mDismissUsingRowTranslationX = dismissUsingRowTranslationX;
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
View child = getChildAt(i);
|
||||
if (child instanceof ExpandableNotificationRow) {
|
||||
((ExpandableNotificationRow) child).setDismissUsingRowTranslationX(
|
||||
dismissUsingRowTranslationX);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if we're launching a notification right now.
|
||||
*/
|
||||
@@ -5258,6 +5298,19 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the total translation needed when dismissing.
|
||||
*/
|
||||
public float getTotalTranslationLength(View animView) {
|
||||
if (!mDismissUsingRowTranslationX) {
|
||||
return animView.getMeasuredWidth();
|
||||
}
|
||||
float notificationWidth = animView.getMeasuredWidth();
|
||||
int containerWidth = getMeasuredWidth();
|
||||
float padding = (containerWidth - notificationWidth) / 2.0f;
|
||||
return containerWidth - padding;
|
||||
}
|
||||
|
||||
/**
|
||||
* A listener that is notified when the empty space below the notifications is clicked on
|
||||
*/
|
||||
|
||||
@@ -383,6 +383,11 @@ public class NotificationStackScrollLayoutController {
|
||||
false /* resetMenu */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTotalTranslationLength(View animView) {
|
||||
return mView.getTotalTranslationLength(animView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSnooze(StatusBarNotification sbn,
|
||||
NotificationSwipeActionHelper.SnoozeOption snoozeOption) {
|
||||
|
||||
@@ -324,6 +324,11 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getTotalTranslationLength(View animView) {
|
||||
return mCallback.getTotalTranslationLength(animView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTranslation(View v, float translate) {
|
||||
if (v instanceof SwipeableView) {
|
||||
@@ -466,6 +471,13 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
|
||||
void onSnooze(StatusBarNotification sbn, SnoozeOption snoozeOption);
|
||||
|
||||
void onDismiss();
|
||||
|
||||
/**
|
||||
* Get the total translation length where we want to swipe to when dismissing the view. By
|
||||
* default this is the size of the view, but can also be larger.
|
||||
* @param animView the view to ask about
|
||||
*/
|
||||
float getTotalTranslationLength(View animView);
|
||||
}
|
||||
|
||||
static class Builder {
|
||||
|
||||
@@ -392,7 +392,7 @@ public class StackStateAnimator {
|
||||
0, () -> removeTransientView(changingView), null);
|
||||
} else if (event.animationType ==
|
||||
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT) {
|
||||
if (Math.abs(changingView.getTranslation()) == changingView.getWidth()
|
||||
if (mHostLayout.isFullySwipedOut(changingView)
|
||||
&& changingView.getTransientContainer() != null) {
|
||||
changingView.getTransientContainer().removeTransientView(changingView);
|
||||
}
|
||||
|
||||
@@ -289,6 +289,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testIconScrollXAfterTranslationAndReset() throws Exception {
|
||||
mGroupRow.setDismissUsingRowTranslationX(false);
|
||||
mGroupRow.setTranslation(50);
|
||||
assertEquals(50, -mGroupRow.getEntry().getIcons().getShelfIcon().getScrollX());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user