Fixed an issue where the unread count would disappear too fast
Especially with images this was leading to really bad transitions since the image would pop over immediately. We now update the counter once the expansion has finished Fixes: 153392205 Test: add conversations with messages with unread count and image, click on it. Change-Id: I2ad2ec6a989a21154e3edbf09aabc6d17ea75bd7
This commit is contained in:
@@ -386,14 +386,17 @@ public class ConversationLayout extends FrameLayout
|
||||
|
||||
/** @hide */
|
||||
public void setUnreadCount(int unreadCount) {
|
||||
mUnreadBadge.setVisibility(mIsCollapsed && unreadCount > 1 ? VISIBLE : GONE);
|
||||
CharSequence text = unreadCount >= 100
|
||||
? getResources().getString(R.string.unread_convo_overflow, 99)
|
||||
: String.format(Locale.getDefault(), "%d", unreadCount);
|
||||
mUnreadBadge.setText(text);
|
||||
mUnreadBadge.setBackgroundTintList(ColorStateList.valueOf(mLayoutColor));
|
||||
boolean needDarkText = ColorUtils.calculateLuminance(mLayoutColor) > 0.5f;
|
||||
mUnreadBadge.setTextColor(needDarkText ? Color.BLACK : Color.WHITE);
|
||||
boolean visible = mIsCollapsed && unreadCount > 1;
|
||||
mUnreadBadge.setVisibility(visible ? VISIBLE : GONE);
|
||||
if (visible) {
|
||||
CharSequence text = unreadCount >= 100
|
||||
? getResources().getString(R.string.unread_convo_overflow, 99)
|
||||
: String.format(Locale.getDefault(), "%d", unreadCount);
|
||||
mUnreadBadge.setText(text);
|
||||
mUnreadBadge.setBackgroundTintList(ColorStateList.valueOf(mLayoutColor));
|
||||
boolean needDarkText = ColorUtils.calculateLuminance(mLayoutColor) > 0.5f;
|
||||
mUnreadBadge.setTextColor(needDarkText ? Color.BLACK : Color.WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
private void addRemoteInputHistoryToMessages(
|
||||
|
||||
@@ -103,12 +103,20 @@ class ConversationNotificationManager @Inject constructor(
|
||||
override fun onEntryInflated(entry: NotificationEntry) {
|
||||
if (!entry.ranking.isConversation) return
|
||||
fun updateCount(isExpanded: Boolean) {
|
||||
if (isExpanded && !notifPanelCollapsed) {
|
||||
if (isExpanded && (!notifPanelCollapsed || entry.isPinnedAndExpanded())) {
|
||||
resetCount(entry.key)
|
||||
entry.row?.let(::resetBadgeUi)
|
||||
}
|
||||
}
|
||||
entry.row?.setOnExpansionChangedListener(::updateCount)
|
||||
entry.row?.setOnExpansionChangedListener { isExpanded ->
|
||||
if (entry.row?.isShown == true && isExpanded) {
|
||||
entry.row.performOnIntrinsicHeightReached {
|
||||
updateCount(isExpanded)
|
||||
}
|
||||
} else {
|
||||
updateCount(isExpanded)
|
||||
}
|
||||
}
|
||||
updateCount(entry.row?.isExpanded == true)
|
||||
}
|
||||
|
||||
@@ -169,7 +177,8 @@ class ConversationNotificationManager @Inject constructor(
|
||||
|
||||
private fun resetBadgeUi(row: ExpandableNotificationRow): Unit =
|
||||
(row.layouts?.asSequence() ?: emptySequence())
|
||||
.mapNotNull { layout -> layout.contractedChild as? ConversationLayout }
|
||||
.flatMap { layout -> layout.allViews.asSequence()}
|
||||
.mapNotNull { view -> view as? ConversationLayout }
|
||||
.forEach { convoLayout -> convoLayout.setUnreadCount(0) }
|
||||
|
||||
private data class ConversationState(val unreadCount: Int, val notification: Notification)
|
||||
|
||||
@@ -610,6 +610,13 @@ public final class NotificationEntry extends ListEntry {
|
||||
return row != null && row.isPinned();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this entry pinned and was expanded while doing so
|
||||
*/
|
||||
public boolean isPinnedAndExpanded() {
|
||||
return row != null && row.isPinnedAndExpanded();
|
||||
}
|
||||
|
||||
public void setRowPinned(boolean pinned) {
|
||||
if (row != null) row.setPinned(pinned);
|
||||
}
|
||||
|
||||
@@ -287,6 +287,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
if (isPinned()) {
|
||||
nowExpanded = !mExpandedWhenPinned;
|
||||
mExpandedWhenPinned = nowExpanded;
|
||||
// Also notify any expansion changed listeners. This is necessary since the
|
||||
// expansion doesn't actually change (it's already system expanded) but it
|
||||
// changes visually
|
||||
if (mExpansionChangedListener != null) {
|
||||
mExpansionChangedListener.onExpansionChanged(nowExpanded);
|
||||
}
|
||||
} else {
|
||||
nowExpanded = !isExpanded();
|
||||
setUserExpanded(nowExpanded);
|
||||
@@ -329,6 +335,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
private NotificationInlineImageResolver mImageResolver;
|
||||
private NotificationMediaManager mMediaManager;
|
||||
@Nullable private OnExpansionChangedListener mExpansionChangedListener;
|
||||
@Nullable private Runnable mOnIntrinsicHeightReachedRunnable;
|
||||
|
||||
private SystemNotificationAsyncTask mSystemNotificationAsyncTask =
|
||||
new SystemNotificationAsyncTask();
|
||||
@@ -361,6 +368,16 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
return Arrays.copyOf(mLayouts, mLayouts.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this entry pinned and was expanded while doing so
|
||||
*/
|
||||
public boolean isPinnedAndExpanded() {
|
||||
if (!isPinned()) {
|
||||
return false;
|
||||
}
|
||||
return mExpandedWhenPinned;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGroupExpansionChanging() {
|
||||
if (isChildInGroup()) {
|
||||
@@ -2714,6 +2731,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
if (mMenuRow != null && mMenuRow.getMenuView() != null) {
|
||||
mMenuRow.onParentHeightUpdate();
|
||||
}
|
||||
handleIntrinsicHeightReached();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2931,6 +2949,24 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
mExpansionChangedListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an action when the notification height has reached its intrinsic height.
|
||||
*
|
||||
* @param runnable the runnable to run
|
||||
*/
|
||||
public void performOnIntrinsicHeightReached(@Nullable Runnable runnable) {
|
||||
mOnIntrinsicHeightReachedRunnable = runnable;
|
||||
handleIntrinsicHeightReached();
|
||||
}
|
||||
|
||||
private void handleIntrinsicHeightReached() {
|
||||
if (mOnIntrinsicHeightReachedRunnable != null
|
||||
&& getActualHeight() == getIntrinsicHeight()) {
|
||||
mOnIntrinsicHeightReachedRunnable.run();
|
||||
mOnIntrinsicHeightReachedRunnable = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfoInternal(info);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.notification.row;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
@@ -985,6 +986,14 @@ public class NotificationContentView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
public @NonNull View[] getAllViews() {
|
||||
return new View[] {
|
||||
mContractedChild,
|
||||
mHeadsUpChild,
|
||||
mExpandedChild,
|
||||
mSingleLineView };
|
||||
}
|
||||
|
||||
public NotificationViewWrapper getVisibleWrapper(int visibleType) {
|
||||
switch (visibleType) {
|
||||
case VISIBLE_TYPE_EXPANDED:
|
||||
|
||||
Reference in New Issue
Block a user