Merge "Fixed the animations of Messaging Layout, leading to overlaps" into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d982210d89
@@ -100,7 +100,6 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
|
||||
super.onFinishInflate();
|
||||
mMessageContainer = findViewById(R.id.group_message_container);
|
||||
mSenderName = findViewById(R.id.message_name);
|
||||
mSenderName.addOnLayoutChangeListener(MessagingLayout.MESSAGING_PROPERTY_ANIMATOR);
|
||||
mAvatarView = findViewById(R.id.message_icon);
|
||||
mImageContainer = findViewById(R.id.messaging_group_icon_container);
|
||||
mSendingSpinner = findViewById(R.id.messaging_group_sending_progress);
|
||||
@@ -190,73 +189,66 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
|
||||
}
|
||||
|
||||
public void removeMessage(MessagingMessage messagingMessage) {
|
||||
ViewGroup messageParent = (ViewGroup) messagingMessage.getView().getParent();
|
||||
messageParent.removeView(messagingMessage.getView());
|
||||
View view = messagingMessage.getView();
|
||||
boolean wasShown = view.isShown();
|
||||
ViewGroup messageParent = (ViewGroup) view.getParent();
|
||||
if (messageParent == null) {
|
||||
return;
|
||||
}
|
||||
messageParent.removeView(view);
|
||||
Runnable recycleRunnable = () -> {
|
||||
messageParent.removeTransientView(messagingMessage.getView());
|
||||
messageParent.removeTransientView(view);
|
||||
messagingMessage.recycle();
|
||||
if (mMessageContainer.getChildCount() == 0
|
||||
&& mMessageContainer.getTransientViewCount() == 0
|
||||
&& mImageContainer.getChildCount() == 0) {
|
||||
ViewParent parent = getParent();
|
||||
if (parent instanceof ViewGroup) {
|
||||
((ViewGroup) parent).removeView(MessagingGroup.this);
|
||||
}
|
||||
setAvatar(null);
|
||||
mAvatarView.setAlpha(1.0f);
|
||||
mAvatarView.setTranslationY(0.0f);
|
||||
mSenderName.setAlpha(1.0f);
|
||||
mSenderName.setTranslationY(0.0f);
|
||||
mIsolatedMessage = null;
|
||||
mMessages = null;
|
||||
sInstancePool.release(MessagingGroup.this);
|
||||
}
|
||||
};
|
||||
if (isShown()) {
|
||||
messageParent.addTransientView(messagingMessage.getView(), 0);
|
||||
performRemoveAnimation(messagingMessage.getView(), recycleRunnable);
|
||||
if (mMessageContainer.getChildCount() == 0
|
||||
&& mImageContainer.getChildCount() == 0) {
|
||||
removeGroupAnimated(null);
|
||||
}
|
||||
if (wasShown && !MessagingLinearLayout.isGone(view)) {
|
||||
messageParent.addTransientView(view, 0);
|
||||
performRemoveAnimation(view, recycleRunnable);
|
||||
} else {
|
||||
recycleRunnable.run();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void removeGroupAnimated(Runnable endAction) {
|
||||
performRemoveAnimation(mAvatarView, null);
|
||||
performRemoveAnimation(mSenderName, null);
|
||||
boolean endActionTriggered = false;
|
||||
for (int i = mMessageContainer.getChildCount() - 1; i >= 0; i--) {
|
||||
View child = mMessageContainer.getChildAt(i);
|
||||
if (child.getVisibility() == View.GONE) {
|
||||
continue;
|
||||
}
|
||||
final ViewGroup.LayoutParams lp = child.getLayoutParams();
|
||||
if (lp instanceof MessagingLinearLayout.LayoutParams
|
||||
&& ((MessagingLinearLayout.LayoutParams) lp).hide
|
||||
&& !((MessagingLinearLayout.LayoutParams) lp).visibleBefore) {
|
||||
continue;
|
||||
}
|
||||
Runnable childEndAction = endActionTriggered ? null : endAction;
|
||||
performRemoveAnimation(child, childEndAction);
|
||||
endActionTriggered = true;
|
||||
}
|
||||
public void recycle() {
|
||||
if (mIsolatedMessage != null) {
|
||||
performRemoveAnimation(mIsolatedMessage, !endActionTriggered ? endAction : null);
|
||||
endActionTriggered = true;
|
||||
mImageContainer.removeView(mIsolatedMessage);
|
||||
}
|
||||
if (!endActionTriggered && endAction != null) {
|
||||
endAction.run();
|
||||
for (int i = 0; i < mMessages.size(); i++) {
|
||||
MessagingMessage message = mMessages.get(i);
|
||||
mMessageContainer.removeView(message.getView());
|
||||
message.recycle();
|
||||
}
|
||||
setAvatar(null);
|
||||
mAvatarView.setAlpha(1.0f);
|
||||
mAvatarView.setTranslationY(0.0f);
|
||||
mSenderName.setAlpha(1.0f);
|
||||
mSenderName.setTranslationY(0.0f);
|
||||
setAlpha(1.0f);
|
||||
mIsolatedMessage = null;
|
||||
mMessages = null;
|
||||
mAddedMessages.clear();
|
||||
mFirstLayout = true;
|
||||
MessagingPropertyAnimator.recycle(this);
|
||||
sInstancePool.release(MessagingGroup.this);
|
||||
}
|
||||
|
||||
public void removeGroupAnimated(Runnable endAction) {
|
||||
performRemoveAnimation(this, () -> {
|
||||
setAlpha(1.0f);
|
||||
MessagingPropertyAnimator.setToLaidOutPosition(this);
|
||||
if (endAction != null) {
|
||||
endAction.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void performRemoveAnimation(View message, Runnable endAction) {
|
||||
MessagingPropertyAnimator.fadeOut(message, endAction);
|
||||
MessagingPropertyAnimator.startLocalTranslationTo(message,
|
||||
(int) (-getHeight() * 0.5f), MessagingLayout.FAST_OUT_LINEAR_IN);
|
||||
performRemoveAnimation(message, -message.getHeight(), endAction);
|
||||
}
|
||||
|
||||
private void performRemoveAnimation(View view, int disappearTranslation, Runnable endAction) {
|
||||
MessagingPropertyAnimator.startLocalTranslationTo(view, disappearTranslation,
|
||||
MessagingLayout.FAST_OUT_LINEAR_IN);
|
||||
MessagingPropertyAnimator.fadeOut(view, endAction);
|
||||
}
|
||||
|
||||
public CharSequence getSenderName() {
|
||||
@@ -341,6 +333,11 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Icon getAvatarSymbolIfMatching(CharSequence avatarName, String avatarSymbol,
|
||||
int layoutColor) {
|
||||
if (mAvatarName.equals(avatarName) && mAvatarSymbol.equals(avatarSymbol)
|
||||
@@ -458,6 +455,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
if (!mAddedMessages.isEmpty()) {
|
||||
final boolean firstLayout = mFirstLayout;
|
||||
getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
@@ -466,7 +464,7 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
|
||||
continue;
|
||||
}
|
||||
MessagingPropertyAnimator.fadeIn(message.getView());
|
||||
if (!mFirstLayout) {
|
||||
if (!firstLayout) {
|
||||
MessagingPropertyAnimator.startLocalTranslationFrom(message.getView(),
|
||||
message.getView().getHeight(),
|
||||
MessagingLayout.LINEAR_OUT_SLOW_IN);
|
||||
|
||||
@@ -170,8 +170,6 @@ public class MessagingImageMessage extends ImageView implements MessagingMessage
|
||||
|
||||
public void recycle() {
|
||||
MessagingMessage.super.recycle();
|
||||
setAlpha(1.0f);
|
||||
setTranslationY(0);
|
||||
setImageBitmap(null);
|
||||
mDrawable = null;
|
||||
sInstancePool.release(this);
|
||||
|
||||
@@ -180,8 +180,13 @@ public class MessagingLayout extends FrameLayout {
|
||||
List<MessagingMessage> historicMessages = createMessages(newHistoricMessages,
|
||||
true /* isHistoric */);
|
||||
List<MessagingMessage> messages = createMessages(newMessages, false /* isHistoric */);
|
||||
|
||||
ArrayList<MessagingGroup> oldGroups = new ArrayList<>(mGroups);
|
||||
addMessagesToGroups(historicMessages, messages, showSpinner);
|
||||
|
||||
// Let's first check which groups were removed altogether and remove them in one animation
|
||||
removeGroups(oldGroups);
|
||||
|
||||
// Let's remove the remaining messages
|
||||
mMessages.forEach(REMOVE_MESSAGE);
|
||||
mHistoricMessages.forEach(REMOVE_MESSAGE);
|
||||
@@ -193,6 +198,31 @@ public class MessagingLayout extends FrameLayout {
|
||||
updateTitleAndNamesDisplay();
|
||||
}
|
||||
|
||||
private void removeGroups(ArrayList<MessagingGroup> oldGroups) {
|
||||
int size = oldGroups.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
MessagingGroup group = oldGroups.get(i);
|
||||
if (!mGroups.contains(group)) {
|
||||
List<MessagingMessage> messages = group.getMessages();
|
||||
Runnable endRunnable = () -> {
|
||||
mMessagingLinearLayout.removeTransientView(group);
|
||||
group.recycle();
|
||||
};
|
||||
|
||||
boolean wasShown = group.isShown();
|
||||
mMessagingLinearLayout.removeView(group);
|
||||
if (wasShown && !MessagingLinearLayout.isGone(group)) {
|
||||
mMessagingLinearLayout.addTransientView(group, 0);
|
||||
group.removeGroupAnimated(endRunnable);
|
||||
} else {
|
||||
endRunnable.run();
|
||||
}
|
||||
mMessages.removeAll(messages);
|
||||
mHistoricMessages.removeAll(messages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTitleAndNamesDisplay() {
|
||||
ArrayMap<CharSequence, String> uniqueNames = new ArrayMap<>();
|
||||
ArrayMap<Character, CharSequence> uniqueCharacters = new ArrayMap<>();
|
||||
|
||||
@@ -163,15 +163,6 @@ public class MessagingLinearLayout extends ViewGroup {
|
||||
}
|
||||
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
MessagingChild messagingChild = (MessagingChild) child;
|
||||
if (lp.hide) {
|
||||
if (shown && lp.visibleBefore) {
|
||||
messagingChild.hideAnimated();
|
||||
}
|
||||
lp.visibleBefore = false;
|
||||
continue;
|
||||
} else {
|
||||
lp.visibleBefore = true;
|
||||
}
|
||||
|
||||
final int childWidth = child.getMeasuredWidth();
|
||||
final int childHeight = child.getMeasuredHeight();
|
||||
@@ -182,6 +173,19 @@ public class MessagingLinearLayout extends ViewGroup {
|
||||
} else {
|
||||
childLeft = paddingLeft + lp.leftMargin;
|
||||
}
|
||||
if (lp.hide) {
|
||||
if (shown && lp.visibleBefore) {
|
||||
// We still want to lay out the child to have great animations
|
||||
child.layout(childLeft, childTop, childLeft + childWidth,
|
||||
childTop + lp.lastVisibleHeight);
|
||||
messagingChild.hideAnimated();
|
||||
}
|
||||
lp.visibleBefore = false;
|
||||
continue;
|
||||
} else {
|
||||
lp.visibleBefore = true;
|
||||
lp.lastVisibleHeight = childHeight;
|
||||
}
|
||||
|
||||
if (!first) {
|
||||
childTop += mSpacing;
|
||||
@@ -228,6 +232,18 @@ public class MessagingLinearLayout extends ViewGroup {
|
||||
return copy;
|
||||
}
|
||||
|
||||
public static boolean isGone(View view) {
|
||||
if (view.getVisibility() == View.GONE) {
|
||||
return true;
|
||||
}
|
||||
final ViewGroup.LayoutParams lp = view.getLayoutParams();
|
||||
if (lp instanceof MessagingLinearLayout.LayoutParams
|
||||
&& ((MessagingLinearLayout.LayoutParams) lp).hide) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets how many lines should be displayed at most
|
||||
*/
|
||||
@@ -263,6 +279,7 @@ public class MessagingLinearLayout extends ViewGroup {
|
||||
|
||||
public boolean hide = false;
|
||||
public boolean visibleBefore = false;
|
||||
public int lastVisibleHeight;
|
||||
|
||||
public LayoutParams(Context c, AttributeSet attrs) {
|
||||
super(c, attrs);
|
||||
|
||||
@@ -124,8 +124,7 @@ public interface MessagingMessage extends MessagingLinearLayout.MessagingChild {
|
||||
@Override
|
||||
default void hideAnimated() {
|
||||
setIsHidingAnimated(true);
|
||||
getGroup().performRemoveAnimation(getState().getHostView(),
|
||||
() -> setIsHidingAnimated(false));
|
||||
getGroup().performRemoveAnimation(getView(), () -> setIsHidingAnimated(false));
|
||||
}
|
||||
|
||||
default boolean hasOverlappingRendering() {
|
||||
@@ -133,7 +132,7 @@ public interface MessagingMessage extends MessagingLinearLayout.MessagingChild {
|
||||
}
|
||||
|
||||
default void recycle() {
|
||||
getState().reset();
|
||||
getState().recycle();
|
||||
}
|
||||
|
||||
default View getView() {
|
||||
|
||||
@@ -72,7 +72,10 @@ public class MessagingMessageState {
|
||||
return mHostView;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
public void recycle() {
|
||||
mHostView.setAlpha(1.0f);
|
||||
mHostView.setTranslationY(0);
|
||||
MessagingPropertyAnimator.recycle(mHostView);
|
||||
mIsHidingAnimated = false;
|
||||
mIsHistoric = false;
|
||||
mGroup = null;
|
||||
|
||||
@@ -31,111 +31,125 @@ import com.android.internal.R;
|
||||
* A listener that automatically starts animations when the layout bounds change.
|
||||
*/
|
||||
public class MessagingPropertyAnimator implements View.OnLayoutChangeListener {
|
||||
static final long APPEAR_ANIMATION_LENGTH = 210;
|
||||
private static final long APPEAR_ANIMATION_LENGTH = 210;
|
||||
private static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
|
||||
public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
|
||||
private static final int TAG_LOCAL_TRANSLATION_ANIMATOR = R.id.tag_local_translation_y_animator;
|
||||
private static final int TAG_LOCAL_TRANSLATION_Y = R.id.tag_local_translation_y;
|
||||
private static final int TAG_TOP_ANIMATOR = R.id.tag_top_animator;
|
||||
private static final int TAG_TOP = R.id.tag_top_override;
|
||||
private static final int TAG_LAYOUT_TOP = R.id.tag_layout_top;
|
||||
private static final int TAG_FIRST_LAYOUT = R.id.tag_is_first_layout;
|
||||
private static final int TAG_ALPHA_ANIMATOR = R.id.tag_alpha_animator;
|
||||
private static final ViewClippingUtil.ClippingParameters CLIPPING_PARAMETERS =
|
||||
view -> view.getId() == com.android.internal.R.id.notification_messaging;
|
||||
private static final IntProperty<View> LOCAL_TRANSLATION_Y =
|
||||
new IntProperty<View>("localTranslationY") {
|
||||
private static final IntProperty<View> TOP =
|
||||
new IntProperty<View>("top") {
|
||||
@Override
|
||||
public void setValue(View object, int value) {
|
||||
setLocalTranslationY(object, value);
|
||||
setTop(object, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer get(View object) {
|
||||
return getLocalTranslationY(object);
|
||||
return getTop(object);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
|
||||
int oldTop, int oldRight, int oldBottom) {
|
||||
int oldHeight = oldBottom - oldTop;
|
||||
Integer layoutTop = (Integer) v.getTag(TAG_LAYOUT_TOP);
|
||||
if (layoutTop != null) {
|
||||
oldTop = layoutTop;
|
||||
}
|
||||
int topChange = oldTop - top;
|
||||
if (oldHeight == 0 || topChange == 0 || !v.isShown() || isGone(v)) {
|
||||
// First layout
|
||||
setLayoutTop(v, top);
|
||||
if (isFirstLayout(v)) {
|
||||
setFirstLayout(v, false /* first */);
|
||||
setTop(v, top);
|
||||
return;
|
||||
}
|
||||
if (layoutTop != null) {
|
||||
v.setTagInternal(TAG_LAYOUT_TOP, top);
|
||||
}
|
||||
int newHeight = bottom - top;
|
||||
int heightDifference = oldHeight - newHeight;
|
||||
// Only add the difference if the height changes and it's getting smaller
|
||||
heightDifference = Math.max(heightDifference, 0);
|
||||
startLocalTranslationFrom(v, topChange + heightDifference + getLocalTranslationY(v));
|
||||
startTopAnimation(v, getTop(v), top, MessagingLayout.FAST_OUT_SLOW_IN);
|
||||
}
|
||||
|
||||
private boolean isGone(View view) {
|
||||
if (view.getVisibility() == View.GONE) {
|
||||
return true;
|
||||
}
|
||||
final ViewGroup.LayoutParams lp = view.getLayoutParams();
|
||||
if (lp instanceof MessagingLinearLayout.LayoutParams
|
||||
&& ((MessagingLinearLayout.LayoutParams) lp).hide) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void startLocalTranslationFrom(View v, int startTranslation) {
|
||||
startLocalTranslationFrom(v, startTranslation, MessagingLayout.FAST_OUT_SLOW_IN);
|
||||
}
|
||||
|
||||
public static void startLocalTranslationFrom(View v, int startTranslation,
|
||||
Interpolator interpolator) {
|
||||
startLocalTranslation(v, startTranslation, 0, interpolator);
|
||||
}
|
||||
|
||||
public static void startLocalTranslationTo(View v, int endTranslation,
|
||||
Interpolator interpolator) {
|
||||
startLocalTranslation(v, getLocalTranslationY(v), endTranslation, interpolator);
|
||||
}
|
||||
|
||||
public static int getLocalTranslationY(View v) {
|
||||
Integer tag = (Integer) v.getTag(TAG_LOCAL_TRANSLATION_Y);
|
||||
private static boolean isFirstLayout(View view) {
|
||||
Boolean tag = (Boolean) view.getTag(TAG_FIRST_LAYOUT);
|
||||
if (tag == null) {
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
private static void setLocalTranslationY(View v, int value) {
|
||||
v.setTagInternal(TAG_LOCAL_TRANSLATION_Y, value);
|
||||
public static void recycle(View view) {
|
||||
setFirstLayout(view, true /* first */);
|
||||
}
|
||||
|
||||
private static void setFirstLayout(View view, boolean first) {
|
||||
view.setTagInternal(TAG_FIRST_LAYOUT, first);
|
||||
}
|
||||
|
||||
private static void setLayoutTop(View view, int top) {
|
||||
view.setTagInternal(TAG_LAYOUT_TOP, top);
|
||||
}
|
||||
|
||||
public static int getLayoutTop(View view) {
|
||||
Integer tag = (Integer) view.getTag(TAG_LAYOUT_TOP);
|
||||
if (tag == null) {
|
||||
return getTop(view);
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a translation animation from a start offset to the laid out location
|
||||
* @param view The view to animate
|
||||
* @param startTranslation The starting translation to start from.
|
||||
* @param interpolator The interpolator to use.
|
||||
*/
|
||||
public static void startLocalTranslationFrom(View view, int startTranslation,
|
||||
Interpolator interpolator) {
|
||||
startTopAnimation(view, getTop(view) + startTranslation, getLayoutTop(view), interpolator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a translation animation from a start offset to the laid out location
|
||||
* @param view The view to animate
|
||||
* @param endTranslation The end translation to go to.
|
||||
* @param interpolator The interpolator to use.
|
||||
*/
|
||||
public static void startLocalTranslationTo(View view, int endTranslation,
|
||||
Interpolator interpolator) {
|
||||
int top = getTop(view);
|
||||
startTopAnimation(view, top, top + endTranslation, interpolator);
|
||||
}
|
||||
|
||||
public static int getTop(View v) {
|
||||
Integer tag = (Integer) v.getTag(TAG_TOP);
|
||||
if (tag == null) {
|
||||
return v.getTop();
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
private static void setTop(View v, int value) {
|
||||
v.setTagInternal(TAG_TOP, value);
|
||||
updateTopAndBottom(v);
|
||||
}
|
||||
|
||||
private static void updateTopAndBottom(View v) {
|
||||
int layoutTop = (int) v.getTag(TAG_LAYOUT_TOP);
|
||||
int localTranslation = getLocalTranslationY(v);
|
||||
int top = getTop(v);
|
||||
int height = v.getHeight();
|
||||
v.setTop(layoutTop + localTranslation);
|
||||
v.setBottom(layoutTop + height + localTranslation);
|
||||
v.setTop(top);
|
||||
v.setBottom(height + top);
|
||||
}
|
||||
|
||||
private static void startLocalTranslation(final View v, int start, int end,
|
||||
private static void startTopAnimation(final View v, int start, int end,
|
||||
Interpolator interpolator) {
|
||||
ObjectAnimator existing = (ObjectAnimator) v.getTag(TAG_LOCAL_TRANSLATION_ANIMATOR);
|
||||
ObjectAnimator existing = (ObjectAnimator) v.getTag(TAG_TOP_ANIMATOR);
|
||||
if (existing != null) {
|
||||
existing.cancel();
|
||||
}
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(v, LOCAL_TRANSLATION_Y, start, end);
|
||||
Integer layoutTop = (Integer) v.getTag(TAG_LAYOUT_TOP);
|
||||
if (layoutTop == null) {
|
||||
layoutTop = v.getTop();
|
||||
v.setTagInternal(TAG_LAYOUT_TOP, layoutTop);
|
||||
if (!v.isShown() || start == end
|
||||
|| (MessagingLinearLayout.isGone(v) && !isHidingAnimated(v))) {
|
||||
setTop(v, end);
|
||||
return;
|
||||
}
|
||||
setLocalTranslationY(v, start);
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(v, TOP, start, end);
|
||||
setTop(v, start);
|
||||
animator.setInterpolator(interpolator);
|
||||
animator.setDuration(APPEAR_ANIMATION_LENGTH);
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@@ -143,12 +157,8 @@ public class MessagingPropertyAnimator implements View.OnLayoutChangeListener {
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
v.setTagInternal(TAG_LOCAL_TRANSLATION_ANIMATOR, null);
|
||||
v.setTagInternal(TAG_TOP_ANIMATOR, null);
|
||||
setClippingDeactivated(v, false);
|
||||
if (!mCancelled) {
|
||||
setLocalTranslationY(v, 0);
|
||||
v.setTagInternal(TAG_LAYOUT_TOP, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -157,10 +167,17 @@ public class MessagingPropertyAnimator implements View.OnLayoutChangeListener {
|
||||
}
|
||||
});
|
||||
setClippingDeactivated(v, true);
|
||||
v.setTagInternal(TAG_LOCAL_TRANSLATION_ANIMATOR, animator);
|
||||
v.setTagInternal(TAG_TOP_ANIMATOR, animator);
|
||||
animator.start();
|
||||
}
|
||||
|
||||
private static boolean isHidingAnimated(View v) {
|
||||
if (v instanceof MessagingLinearLayout.MessagingChild) {
|
||||
return ((MessagingLinearLayout.MessagingChild) v).isHidingAnimated();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void fadeIn(final View v) {
|
||||
ObjectAnimator existing = (ObjectAnimator) v.getTag(TAG_ALPHA_ANIMATOR);
|
||||
if (existing != null) {
|
||||
@@ -199,6 +216,13 @@ public class MessagingPropertyAnimator implements View.OnLayoutChangeListener {
|
||||
if (existing != null) {
|
||||
existing.cancel();
|
||||
}
|
||||
if (!view.isShown() || (MessagingLinearLayout.isGone(view) && !isHidingAnimated(view))) {
|
||||
view.setAlpha(0.0f);
|
||||
if (endAction != null) {
|
||||
endAction.run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.ALPHA,
|
||||
view.getAlpha(), 0.0f);
|
||||
animator.setInterpolator(ALPHA_OUT);
|
||||
@@ -224,10 +248,14 @@ public class MessagingPropertyAnimator implements View.OnLayoutChangeListener {
|
||||
}
|
||||
|
||||
public static boolean isAnimatingTranslation(View v) {
|
||||
return v.getTag(TAG_LOCAL_TRANSLATION_ANIMATOR) != null;
|
||||
return v.getTag(TAG_TOP_ANIMATOR) != null;
|
||||
}
|
||||
|
||||
public static boolean isAnimatingAlpha(View v) {
|
||||
return v.getTag(TAG_ALPHA_ANIMATOR) != null;
|
||||
}
|
||||
|
||||
public static void setToLaidOutPosition(View view) {
|
||||
setTop(view, getLayoutTop(view));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,8 +92,6 @@ public class MessagingTextMessage extends ImageFloatingTextView implements Messa
|
||||
|
||||
public void recycle() {
|
||||
MessagingMessage.super.recycle();
|
||||
setAlpha(1.0f);
|
||||
setTranslationY(0);
|
||||
sInstancePool.release(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -140,15 +140,18 @@
|
||||
<!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_MOVE_WINDOW}. -->
|
||||
<item type="id" name="accessibilityActionMoveWindow" />
|
||||
|
||||
<!-- A tag used to save an animator in local y translation -->
|
||||
<item type="id" name="tag_local_translation_y_animator" />
|
||||
<!-- A tag used to save an animator in top -->
|
||||
<item type="id" name="tag_top_animator" />
|
||||
|
||||
<!-- A tag used to save the local translation y -->
|
||||
<item type="id" name="tag_local_translation_y" />
|
||||
<!-- A tag used to save the current top override -->
|
||||
<item type="id" name="tag_top_override" />
|
||||
|
||||
<!-- A tag used to save the original top of a view -->
|
||||
<item type="id" name="tag_layout_top" />
|
||||
|
||||
<!-- A tag used to save whether a view was laid out before -->
|
||||
<item type="id" name="tag_is_first_layout" />
|
||||
|
||||
<!-- A tag used to save an animator in alpha -->
|
||||
<item type="id" name="tag_alpha_animator" />
|
||||
|
||||
|
||||
@@ -3260,9 +3260,10 @@
|
||||
<java-symbol type="id" name="message_name" />
|
||||
<java-symbol type="id" name="message_icon" />
|
||||
<java-symbol type="id" name="group_message_container" />
|
||||
<java-symbol type="id" name="tag_local_translation_y_animator" />
|
||||
<java-symbol type="id" name="tag_local_translation_y" />
|
||||
<java-symbol type="id" name="tag_top_animator" />
|
||||
<java-symbol type="id" name="tag_top_override" />
|
||||
<java-symbol type="id" name="tag_layout_top" />
|
||||
<java-symbol type="id" name="tag_is_first_layout" />
|
||||
<java-symbol type="id" name="tag_alpha_animator" />
|
||||
<java-symbol type="id" name="clip_children_set_tag" />
|
||||
<java-symbol type="id" name="clip_to_padding_tag" />
|
||||
|
||||
@@ -16,11 +16,8 @@
|
||||
|
||||
package com.android.systemui.statusbar.notification;
|
||||
|
||||
import android.util.ArraySet;
|
||||
import android.util.Pools;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
@@ -411,7 +408,8 @@ public class TransformState {
|
||||
mOwnPosition[1] -= (1.0f - mTransformedView.getScaleY()) * mTransformedView.getPivotY();
|
||||
|
||||
// Remove local translations
|
||||
mOwnPosition[1] -= MessagingPropertyAnimator.getLocalTranslationY(mTransformedView);
|
||||
mOwnPosition[1] -= MessagingPropertyAnimator.getTop(mTransformedView)
|
||||
- MessagingPropertyAnimator.getLayoutTop(mTransformedView);
|
||||
return mOwnPosition;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user