Merge "Update notification popup UI." into sc-dev am: 1bfd350ead am: 11a9b035f3
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/15017911 Change-Id: I84468fcb9e75a5ade2faaeb77ba289015f513c1f
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
|
||||||
|
<solid android:color="?attr/popupNotificationDotColor"/>
|
||||||
|
|
||||||
|
<size
|
||||||
|
android:width="@dimen/notification_circle_icon_size"
|
||||||
|
android:height="@dimen/notification_circle_icon_size"/>
|
||||||
|
</shape>
|
||||||
@@ -23,35 +23,36 @@
|
|||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/header"
|
android:id="@+id/header"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/notification_header_height"
|
android:layout_height="wrap_content"
|
||||||
android:paddingEnd="@dimen/notification_padding_end"
|
android:paddingEnd="@dimen/notification_padding"
|
||||||
android:paddingStart="@dimen/notification_padding_start">
|
android:paddingStart="@dimen/notification_padding">
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/notification_text"
|
android:id="@+id/notification_text"
|
||||||
|
android:paddingTop="@dimen/notification_padding"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="bottom|start"
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:text="@string/notifications_header"
|
android:text="@string/notifications_header"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textSize="@dimen/notification_header_text_size" />
|
android:textSize="@dimen/notification_header_text_size"
|
||||||
|
style="@style/TextHeadline"/>
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/notification_count"
|
android:id="@+id/notification_count"
|
||||||
android:layout_width="@dimen/notification_icon_size"
|
android:layout_width="@dimen/notification_circle_icon_size"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="@dimen/notification_circle_icon_size"
|
||||||
android:layout_gravity="end"
|
android:background="@drawable/notification_circle"
|
||||||
android:fontFamily="sans-serif-medium"
|
android:layout_gravity="bottom|end"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textSize="@dimen/notification_header_count_text_size" />
|
android:textSize="@dimen/notification_header_count_text_size"
|
||||||
|
style="@style/TextHeadline"/>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<!-- Main view -->
|
<!-- Main view -->
|
||||||
<com.android.launcher3.notification.NotificationMainView
|
<com.android.launcher3.notification.NotificationMainView
|
||||||
android:id="@+id/main_view"
|
android:id="@+id/main_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/notification_main_height"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/bg_notification_content"
|
|
||||||
android:focusable="true" >
|
android:focusable="true" >
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@@ -61,28 +62,28 @@
|
|||||||
android:background="?attr/popupColorPrimary"
|
android:background="?attr/popupColorPrimary"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingBottom="14dp"
|
android:paddingTop="@dimen/notification_padding"
|
||||||
android:paddingEnd="@dimen/notification_main_text_padding_end"
|
android:paddingBottom="@dimen/notification_padding"
|
||||||
android:paddingStart="@dimen/notification_padding_start">
|
android:paddingEnd="@dimen/notification_padding"
|
||||||
|
android:paddingStart="@dimen/notification_main_text_padding_start">
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/title"
|
android:id="@+id/title"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:fontFamily="sans-serif"
|
|
||||||
android:lines="1"
|
android:lines="1"
|
||||||
android:textAlignment="viewStart"
|
android:textAlignment="viewStart"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textSize="@dimen/notification_main_title_size" />
|
android:textSize="@dimen/notification_main_title_size"
|
||||||
|
style="@style/TextHeadline" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text"
|
android:id="@+id/text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:fontFamily="sans-serif"
|
|
||||||
android:lines="1"
|
android:lines="1"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textSize="@dimen/notification_main_text_size" />
|
android:textSize="@dimen/notification_main_text_size" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -90,37 +91,9 @@
|
|||||||
android:id="@+id/popup_item_icon"
|
android:id="@+id/popup_item_icon"
|
||||||
android:layout_width="@dimen/notification_icon_size"
|
android:layout_width="@dimen/notification_icon_size"
|
||||||
android:layout_height="@dimen/notification_icon_size"
|
android:layout_height="@dimen/notification_icon_size"
|
||||||
android:layout_gravity="center_vertical|end"
|
android:layout_gravity="start"
|
||||||
android:layout_marginBottom="7dp"
|
android:layout_marginTop="@dimen/notification_padding"
|
||||||
android:layout_marginEnd="@dimen/notification_padding_end" />
|
android:layout_marginStart="@dimen/notification_icon_padding" />
|
||||||
|
|
||||||
</com.android.launcher3.notification.NotificationMainView>
|
</com.android.launcher3.notification.NotificationMainView>
|
||||||
|
|
||||||
<!-- Footer -->
|
|
||||||
<com.android.launcher3.notification.NotificationFooterLayout
|
|
||||||
android:id="@+id/footer"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/notification_footer_height"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:clipChildren="false">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/icon_row"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:clipChildren="false"
|
|
||||||
android:clipToPadding="false"
|
|
||||||
android:gravity="end|center_vertical"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:padding="@dimen/notification_footer_icon_row_padding"/>
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/overflow"
|
|
||||||
android:layout_width="@dimen/horizontal_ellipsis_size"
|
|
||||||
android:layout_height="@dimen/horizontal_ellipsis_size"
|
|
||||||
android:layout_gravity="start|center_vertical"
|
|
||||||
android:layout_marginStart="@dimen/horizontal_ellipsis_offset"
|
|
||||||
android:background="@drawable/horizontal_ellipsis" />
|
|
||||||
|
|
||||||
</com.android.launcher3.notification.NotificationFooterLayout>
|
|
||||||
</merge>
|
</merge>
|
||||||
@@ -25,6 +25,9 @@
|
|||||||
<color name="popup_color_secondary_dark">@android:color/system_neutral1_900</color>
|
<color name="popup_color_secondary_dark">@android:color/system_neutral1_900</color>
|
||||||
<color name="popup_color_tertiary_dark">@android:color/system_neutral2_700</color>
|
<color name="popup_color_tertiary_dark">@android:color/system_neutral2_700</color>
|
||||||
|
|
||||||
|
<color name="popup_notification_dot_light">@android:color/system_accent1_100</color>
|
||||||
|
<color name="popup_notification_dot_dark">@android:color/system_accent2_600</color>
|
||||||
|
|
||||||
<color name="workspace_text_color_light">@android:color/system_neutral1_0</color>
|
<color name="workspace_text_color_light">@android:color/system_neutral1_0</color>
|
||||||
<color name="workspace_text_color_dark">@android:color/system_neutral1_1000</color>
|
<color name="workspace_text_color_dark">@android:color/system_neutral1_1000</color>
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
<attr name="iconOnlyShortcutColor" format="color" />
|
<attr name="iconOnlyShortcutColor" format="color" />
|
||||||
<attr name="eduHalfSheetBGColor" format="color" />
|
<attr name="eduHalfSheetBGColor" format="color" />
|
||||||
<attr name="overviewScrimColor" format="color" />
|
<attr name="overviewScrimColor" format="color" />
|
||||||
|
<attr name="popupNotificationDotColor" format="color" />
|
||||||
|
|
||||||
<attr name="folderDotColor" format="color" />
|
<attr name="folderDotColor" format="color" />
|
||||||
<attr name="folderFillColor" format="color" />
|
<attr name="folderFillColor" format="color" />
|
||||||
|
|||||||
@@ -53,6 +53,9 @@
|
|||||||
<color name="popup_color_secondary_dark">#202124</color>
|
<color name="popup_color_secondary_dark">#202124</color>
|
||||||
<color name="popup_color_tertiary_dark">#757575</color> <!-- Gray 600 -->
|
<color name="popup_color_tertiary_dark">#757575</color> <!-- Gray 600 -->
|
||||||
|
|
||||||
|
<color name="popup_notification_dot_light">#FFF</color>
|
||||||
|
<color name="popup_notification_dot_dark">#757575</color>
|
||||||
|
|
||||||
<color name="workspace_text_color_light">#FFF</color>
|
<color name="workspace_text_color_light">#FFF</color>
|
||||||
<color name="workspace_text_color_dark">#FF000000</color>
|
<color name="workspace_text_color_dark">#FF000000</color>
|
||||||
|
|
||||||
|
|||||||
+10
-19
@@ -259,28 +259,19 @@
|
|||||||
|
|
||||||
<!-- Notifications -->
|
<!-- Notifications -->
|
||||||
<dimen name="bg_round_rect_radius">8dp</dimen>
|
<dimen name="bg_round_rect_radius">8dp</dimen>
|
||||||
<dimen name="notification_padding_start">16dp</dimen>
|
<dimen name="notification_padding">16dp</dimen>
|
||||||
<dimen name="notification_padding_end">12dp</dimen>
|
<dimen name="notification_padding_top">18dp</dimen>
|
||||||
<!-- notification_padding_end + (icon_size - footer_icon_size) / 2 -->
|
<dimen name="notification_header_text_size">14sp</dimen>
|
||||||
<dimen name="notification_footer_icon_row_padding">15dp</dimen>
|
|
||||||
<dimen name="notification_header_height">36dp</dimen>
|
|
||||||
<dimen name="notification_main_height">84dp</dimen>
|
|
||||||
<dimen name="notification_footer_height">32dp</dimen>
|
|
||||||
<!-- How much space to keep as padding for the last notification when the footer collapses -->
|
|
||||||
<dimen name="notification_empty_footer_height">6dp</dimen>
|
|
||||||
<dimen name="notification_header_text_size">13sp</dimen>
|
|
||||||
<dimen name="notification_header_count_text_size">12sp</dimen>
|
<dimen name="notification_header_count_text_size">12sp</dimen>
|
||||||
<dimen name="notification_main_title_size">16sp</dimen>
|
<dimen name="notification_main_title_size">14sp</dimen>
|
||||||
<dimen name="notification_main_text_size">14sp</dimen>
|
<dimen name="notification_main_text_size">14sp</dimen>
|
||||||
<dimen name="notification_icon_size">24dp</dimen>
|
<dimen name="notification_circle_icon_size">24dp</dimen>
|
||||||
<dimen name="notification_footer_icon_size">18dp</dimen>
|
<dimen name="notification_icon_size">32dp</dimen>
|
||||||
<!-- notification_icon_size + notification_padding_end + 16dp padding between icon and text -->
|
<!-- Space between edge and icon and icon and text -->
|
||||||
<dimen name="notification_main_text_padding_end">52dp</dimen>
|
<dimen name="notification_icon_padding">12dp</dimen>
|
||||||
|
<!-- notification_icon_padding + notification_icon_size + notification_icon_padding -->
|
||||||
|
<dimen name="notification_main_text_padding_start">56dp</dimen>
|
||||||
<dimen name="horizontal_ellipsis_size">18dp</dimen>
|
<dimen name="horizontal_ellipsis_size">18dp</dimen>
|
||||||
<!-- arrow_horizontal_offset_start - (ellipsis_size - arrow_width) / 2 -->
|
|
||||||
<dimen name="horizontal_ellipsis_offset">19dp</dimen>
|
|
||||||
<dimen name="popup_item_divider_height">0.5dp</dimen>
|
|
||||||
<dimen name="swipe_helper_falsing_threshold">70dp</dimen>
|
|
||||||
|
|
||||||
<!-- Overview -->
|
<!-- Overview -->
|
||||||
<dimen name="options_menu_icon_size">24dp</dimen>
|
<dimen name="options_menu_icon_size">24dp</dimen>
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
<item name="popupColorPrimary">@color/popup_color_primary_light</item>
|
<item name="popupColorPrimary">@color/popup_color_primary_light</item>
|
||||||
<item name="popupColorSecondary">@color/popup_color_secondary_light</item>
|
<item name="popupColorSecondary">@color/popup_color_secondary_light</item>
|
||||||
<item name="popupColorTertiary">@color/popup_color_tertiary_light</item>
|
<item name="popupColorTertiary">@color/popup_color_tertiary_light</item>
|
||||||
|
<item name="popupNotificationDotColor">@color/popup_notification_dot_light</item>
|
||||||
<item name="isMainColorDark">false</item>
|
<item name="isMainColorDark">false</item>
|
||||||
<item name="isWorkspaceDarkText">false</item>
|
<item name="isWorkspaceDarkText">false</item>
|
||||||
<item name="workspaceTextColor">@color/workspace_text_color_light</item>
|
<item name="workspaceTextColor">@color/workspace_text_color_light</item>
|
||||||
@@ -107,6 +108,7 @@
|
|||||||
<item name="popupColorPrimary">@color/popup_color_primary_dark</item>
|
<item name="popupColorPrimary">@color/popup_color_primary_dark</item>
|
||||||
<item name="popupColorSecondary">@color/popup_color_secondary_dark</item>
|
<item name="popupColorSecondary">@color/popup_color_secondary_dark</item>
|
||||||
<item name="popupColorTertiary">@color/popup_color_tertiary_dark</item>
|
<item name="popupColorTertiary">@color/popup_color_tertiary_dark</item>
|
||||||
|
<item name="popupNotificationDotColor">@color/popup_notification_dot_dark</item>
|
||||||
<item name="widgetsTheme">@style/WidgetContainerTheme.Dark</item>
|
<item name="widgetsTheme">@style/WidgetContainerTheme.Dark</item>
|
||||||
<item name="folderDotColor">@color/folder_dot_color</item>
|
<item name="folderDotColor">@color/folder_dot_color</item>
|
||||||
<item name="folderFillColor">@color/folder_background_dark</item>
|
<item name="folderFillColor">@color/folder_background_dark</item>
|
||||||
|
|||||||
@@ -1,238 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.launcher3.notification;
|
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.animation.AnimatorListenerAdapter;
|
|
||||||
import android.animation.AnimatorSet;
|
|
||||||
import android.animation.ObjectAnimator;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
|
|
||||||
import com.android.launcher3.R;
|
|
||||||
import com.android.launcher3.Utilities;
|
|
||||||
import com.android.launcher3.anim.PropertyListBuilder;
|
|
||||||
import com.android.launcher3.anim.PropertyResetListener;
|
|
||||||
import com.android.launcher3.util.Themes;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link FrameLayout} that contains only icons of notifications.
|
|
||||||
* If there are more than {@link #MAX_FOOTER_NOTIFICATIONS} icons, we add a "..." overflow.
|
|
||||||
*/
|
|
||||||
public class NotificationFooterLayout extends FrameLayout {
|
|
||||||
|
|
||||||
public interface IconAnimationEndListener {
|
|
||||||
void onIconAnimationEnd(NotificationInfo animatedNotification);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int MAX_FOOTER_NOTIFICATIONS = 5;
|
|
||||||
|
|
||||||
private static final Rect sTempRect = new Rect();
|
|
||||||
|
|
||||||
private final List<NotificationInfo> mNotifications = new ArrayList<>();
|
|
||||||
private final List<NotificationInfo> mOverflowNotifications = new ArrayList<>();
|
|
||||||
private final boolean mRtl;
|
|
||||||
private final int mBackgroundColor;
|
|
||||||
|
|
||||||
FrameLayout.LayoutParams mIconLayoutParams;
|
|
||||||
private View mOverflowEllipsis;
|
|
||||||
private LinearLayout mIconRow;
|
|
||||||
private NotificationItemView mContainer;
|
|
||||||
|
|
||||||
public NotificationFooterLayout(Context context) {
|
|
||||||
this(context, null, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NotificationFooterLayout(Context context, AttributeSet attrs) {
|
|
||||||
this(context, attrs, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NotificationFooterLayout(Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
|
|
||||||
Resources res = getResources();
|
|
||||||
mRtl = Utilities.isRtl(res);
|
|
||||||
|
|
||||||
int iconSize = res.getDimensionPixelSize(R.dimen.notification_footer_icon_size);
|
|
||||||
mIconLayoutParams = new LayoutParams(iconSize, iconSize);
|
|
||||||
mIconLayoutParams.gravity = Gravity.CENTER_VERTICAL;
|
|
||||||
setWidth((int) res.getDimension(R.dimen.bg_popup_item_width));
|
|
||||||
mBackgroundColor = Themes.getAttrColor(context, R.attr.popupColorPrimary);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compute margin start for each icon such that the icons between the first one and the ellipsis
|
|
||||||
* are evenly spaced out.
|
|
||||||
*/
|
|
||||||
public void setWidth(int width) {
|
|
||||||
if (getLayoutParams() != null) {
|
|
||||||
getLayoutParams().width = width;
|
|
||||||
}
|
|
||||||
Resources res = getResources();
|
|
||||||
int iconSize = res.getDimensionPixelSize(R.dimen.notification_footer_icon_size);
|
|
||||||
|
|
||||||
int paddingEnd = res.getDimensionPixelSize(R.dimen.notification_footer_icon_row_padding);
|
|
||||||
int ellipsisSpace = res.getDimensionPixelSize(R.dimen.horizontal_ellipsis_offset)
|
|
||||||
+ res.getDimensionPixelSize(R.dimen.horizontal_ellipsis_size);
|
|
||||||
int availableIconRowSpace = width - paddingEnd - ellipsisSpace
|
|
||||||
- iconSize * MAX_FOOTER_NOTIFICATIONS;
|
|
||||||
mIconLayoutParams.setMarginStart(availableIconRowSpace / MAX_FOOTER_NOTIFICATIONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onFinishInflate() {
|
|
||||||
super.onFinishInflate();
|
|
||||||
mOverflowEllipsis = findViewById(R.id.overflow);
|
|
||||||
mIconRow = findViewById(R.id.icon_row);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setContainer(NotificationItemView container) {
|
|
||||||
mContainer = container;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Keep track of the NotificationInfo, and then update the UI when
|
|
||||||
* {@link #commitNotificationInfos()} is called.
|
|
||||||
*/
|
|
||||||
public void addNotificationInfo(final NotificationInfo notificationInfo) {
|
|
||||||
if (mNotifications.size() < MAX_FOOTER_NOTIFICATIONS) {
|
|
||||||
mNotifications.add(notificationInfo);
|
|
||||||
} else {
|
|
||||||
mOverflowNotifications.add(notificationInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds icons and potentially overflow text for all of the NotificationInfo's
|
|
||||||
* added using {@link #addNotificationInfo(NotificationInfo)}.
|
|
||||||
*/
|
|
||||||
public void commitNotificationInfos() {
|
|
||||||
mIconRow.removeAllViews();
|
|
||||||
|
|
||||||
for (int i = 0; i < mNotifications.size(); i++) {
|
|
||||||
NotificationInfo info = mNotifications.get(i);
|
|
||||||
addNotificationIconForInfo(info);
|
|
||||||
}
|
|
||||||
updateOverflowEllipsisVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateOverflowEllipsisVisibility() {
|
|
||||||
mOverflowEllipsis.setVisibility(mOverflowNotifications.isEmpty() ? GONE : VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an icon for the given NotificationInfo, and adds it to the icon row.
|
|
||||||
* @return the icon view that was added
|
|
||||||
*/
|
|
||||||
private View addNotificationIconForInfo(NotificationInfo info) {
|
|
||||||
View icon = new View(getContext());
|
|
||||||
icon.setBackground(info.getIconForBackground(getContext(), mBackgroundColor));
|
|
||||||
icon.setOnClickListener(info);
|
|
||||||
icon.setTag(info);
|
|
||||||
icon.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
|
|
||||||
mIconRow.addView(icon, 0, mIconLayoutParams);
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void animateFirstNotificationTo(Rect toBounds,
|
|
||||||
final IconAnimationEndListener callback) {
|
|
||||||
AnimatorSet animation = new AnimatorSet();
|
|
||||||
final View firstNotification = mIconRow.getChildAt(mIconRow.getChildCount() - 1);
|
|
||||||
|
|
||||||
Rect fromBounds = sTempRect;
|
|
||||||
firstNotification.getGlobalVisibleRect(fromBounds);
|
|
||||||
float scale = (float) toBounds.height() / fromBounds.height();
|
|
||||||
Animator moveAndScaleIcon = new PropertyListBuilder().scale(scale)
|
|
||||||
.translationY(toBounds.top - fromBounds.top
|
|
||||||
+ (fromBounds.height() * scale - fromBounds.height()) / 2)
|
|
||||||
.build(firstNotification);
|
|
||||||
moveAndScaleIcon.addListener(new AnimatorListenerAdapter() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationEnd(Animator animation) {
|
|
||||||
callback.onIconAnimationEnd((NotificationInfo) firstNotification.getTag());
|
|
||||||
removeViewFromIconRow(firstNotification);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
animation.play(moveAndScaleIcon);
|
|
||||||
|
|
||||||
// Shift all notifications (not the overflow) over to fill the gap.
|
|
||||||
int gapWidth = mIconLayoutParams.width + mIconLayoutParams.getMarginStart();
|
|
||||||
if (mRtl) {
|
|
||||||
gapWidth = -gapWidth;
|
|
||||||
}
|
|
||||||
if (!mOverflowNotifications.isEmpty()) {
|
|
||||||
NotificationInfo notification = mOverflowNotifications.remove(0);
|
|
||||||
mNotifications.add(notification);
|
|
||||||
View iconFromOverflow = addNotificationIconForInfo(notification);
|
|
||||||
animation.play(ObjectAnimator.ofFloat(iconFromOverflow, ALPHA, 0, 1));
|
|
||||||
}
|
|
||||||
int numIcons = mIconRow.getChildCount() - 1; // All children besides the one leaving.
|
|
||||||
// We have to reset the translation X to 0 when the new main notification
|
|
||||||
// is removed from the footer.
|
|
||||||
PropertyResetListener<View, Float> propertyResetListener
|
|
||||||
= new PropertyResetListener<>(TRANSLATION_X, 0f);
|
|
||||||
for (int i = 0; i < numIcons; i++) {
|
|
||||||
final View child = mIconRow.getChildAt(i);
|
|
||||||
Animator shiftChild = ObjectAnimator.ofFloat(child, TRANSLATION_X, gapWidth);
|
|
||||||
shiftChild.addListener(propertyResetListener);
|
|
||||||
animation.play(shiftChild);
|
|
||||||
}
|
|
||||||
animation.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeViewFromIconRow(View child) {
|
|
||||||
mIconRow.removeView(child);
|
|
||||||
mNotifications.remove(child.getTag());
|
|
||||||
updateOverflowEllipsisVisibility();
|
|
||||||
if (mIconRow.getChildCount() == 0) {
|
|
||||||
// There are no more icons in the footer, so hide it.
|
|
||||||
if (mContainer != null) {
|
|
||||||
mContainer.removeFooter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void trimNotifications(List<String> notifications) {
|
|
||||||
if (!isAttachedToWindow() || mIconRow.getChildCount() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Iterator<NotificationInfo> overflowIterator = mOverflowNotifications.iterator();
|
|
||||||
while (overflowIterator.hasNext()) {
|
|
||||||
if (!notifications.contains(overflowIterator.next().notificationKey)) {
|
|
||||||
overflowIterator.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = mIconRow.getChildCount() - 1; i >= 0; i--) {
|
|
||||||
View child = mIconRow.getChildAt(i);
|
|
||||||
NotificationInfo childInfo = (NotificationInfo) child.getTag();
|
|
||||||
if (!notifications.contains(childInfo.notificationKey)) {
|
|
||||||
removeViewFromIconRow(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,12 +16,8 @@
|
|||||||
|
|
||||||
package com.android.launcher3.notification;
|
package com.android.launcher3.notification;
|
||||||
|
|
||||||
import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
|
|
||||||
|
|
||||||
import android.animation.AnimatorSet;
|
import android.animation.AnimatorSet;
|
||||||
import android.app.Notification;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Outline;
|
import android.graphics.Outline;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
@@ -32,11 +28,10 @@ import android.view.ViewOutlineProvider;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.graphics.IconPalette;
|
|
||||||
import com.android.launcher3.popup.PopupContainerWithArrow;
|
import com.android.launcher3.popup.PopupContainerWithArrow;
|
||||||
import com.android.launcher3.touch.SingleAxisSwipeDetector;
|
|
||||||
import com.android.launcher3.util.Themes;
|
import com.android.launcher3.util.Themes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,39 +45,26 @@ public class NotificationItemView {
|
|||||||
private final PopupContainerWithArrow mPopupContainer;
|
private final PopupContainerWithArrow mPopupContainer;
|
||||||
private final ViewGroup mRootView;
|
private final ViewGroup mRootView;
|
||||||
|
|
||||||
private final TextView mHeaderText;
|
|
||||||
private final TextView mHeaderCount;
|
private final TextView mHeaderCount;
|
||||||
private final NotificationMainView mMainView;
|
private final NotificationMainView mMainView;
|
||||||
private final NotificationFooterLayout mFooter;
|
|
||||||
private final SingleAxisSwipeDetector mSwipeDetector;
|
|
||||||
private final View mIconView;
|
|
||||||
|
|
||||||
private final View mHeader;
|
private final View mHeader;
|
||||||
|
|
||||||
private View mGutter;
|
private View mGutter;
|
||||||
|
|
||||||
private boolean mIgnoreTouch = false;
|
private boolean mIgnoreTouch = false;
|
||||||
private boolean mAnimatingNextIcon;
|
private List<NotificationInfo> mNotificationInfos = new ArrayList<>();
|
||||||
private int mNotificationHeaderTextColor = Notification.COLOR_DEFAULT;
|
|
||||||
|
|
||||||
public NotificationItemView(PopupContainerWithArrow container, ViewGroup rootView) {
|
public NotificationItemView(PopupContainerWithArrow container, ViewGroup rootView) {
|
||||||
mPopupContainer = container;
|
mPopupContainer = container;
|
||||||
mRootView = rootView;
|
mRootView = rootView;
|
||||||
mContext = container.getContext();
|
mContext = container.getContext();
|
||||||
|
|
||||||
mHeaderText = container.findViewById(R.id.notification_text);
|
|
||||||
mHeaderCount = container.findViewById(R.id.notification_count);
|
mHeaderCount = container.findViewById(R.id.notification_count);
|
||||||
mMainView = container.findViewById(R.id.main_view);
|
mMainView = container.findViewById(R.id.main_view);
|
||||||
mFooter = container.findViewById(R.id.footer);
|
|
||||||
mIconView = container.findViewById(R.id.popup_item_icon);
|
|
||||||
|
|
||||||
mHeader = container.findViewById(R.id.header);
|
mHeader = container.findViewById(R.id.header);
|
||||||
|
|
||||||
mSwipeDetector = new SingleAxisSwipeDetector(mContext, mMainView, HORIZONTAL);
|
|
||||||
mSwipeDetector.setDetectableScrollConditions(SingleAxisSwipeDetector.DIRECTION_BOTH, false);
|
|
||||||
mMainView.setSwipeDetector(mSwipeDetector);
|
|
||||||
mFooter.setContainer(this);
|
|
||||||
|
|
||||||
float radius = Themes.getDialogCornerRadius(mContext);
|
float radius = Themes.getDialogCornerRadius(mContext);
|
||||||
rootView.setClipToOutline(true);
|
rootView.setClipToOutline(true);
|
||||||
rootView.setOutlineProvider(new ViewOutlineProvider() {
|
rootView.setOutlineProvider(new ViewOutlineProvider() {
|
||||||
@@ -108,19 +90,6 @@ public class NotificationItemView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets width for notification footer and spaces out items evenly
|
|
||||||
*/
|
|
||||||
public void setFooterWidth(int footerWidth) {
|
|
||||||
mFooter.setWidth(footerWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeFooter() {
|
|
||||||
if (mRootView.indexOfChild(mFooter) >= 0) {
|
|
||||||
mRootView.removeView(mFooter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void inverseGutterMargin() {
|
public void inverseGutterMargin() {
|
||||||
MarginLayoutParams lp = (MarginLayoutParams) mGutter.getLayoutParams();
|
MarginLayoutParams lp = (MarginLayoutParams) mGutter.getLayoutParams();
|
||||||
int top = lp.topMargin;
|
int top = lp.topMargin;
|
||||||
@@ -131,27 +100,28 @@ public class NotificationItemView {
|
|||||||
public void removeAllViews() {
|
public void removeAllViews() {
|
||||||
mRootView.removeView(mMainView);
|
mRootView.removeView(mMainView);
|
||||||
mRootView.removeView(mHeader);
|
mRootView.removeView(mHeader);
|
||||||
|
|
||||||
if (mRootView.indexOfChild(mFooter) >= 0) {
|
|
||||||
mRootView.removeView(mFooter);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mGutter != null) {
|
if (mGutter != null) {
|
||||||
mRootView.removeView(mGutter);
|
mRootView.removeView(mGutter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateHeader(int notificationCount, int iconColor) {
|
/**
|
||||||
mHeaderCount.setText(notificationCount <= 1 ? "" : String.valueOf(notificationCount));
|
* Updates the header text.
|
||||||
if (Color.alpha(iconColor) > 0) {
|
* @param notificationCount The number of notifications.
|
||||||
if (mNotificationHeaderTextColor == Notification.COLOR_DEFAULT) {
|
*/
|
||||||
mNotificationHeaderTextColor =
|
public void updateHeader(int notificationCount) {
|
||||||
IconPalette.resolveContrastColor(mContext, iconColor,
|
final String text;
|
||||||
Themes.getAttrColor(mContext, R.attr.popupColorPrimary));
|
final int visibility;
|
||||||
}
|
if (notificationCount <= 1) {
|
||||||
mHeaderText.setTextColor(mNotificationHeaderTextColor);
|
text = "";
|
||||||
mHeaderCount.setTextColor(mNotificationHeaderTextColor);
|
visibility = View.INVISIBLE;
|
||||||
|
} else {
|
||||||
|
text = String.valueOf(notificationCount);
|
||||||
|
visibility = View.VISIBLE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
mHeaderCount.setText(text);
|
||||||
|
mHeaderCount.setVisibility(visibility);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||||
@@ -171,53 +141,39 @@ public class NotificationItemView {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mSwipeDetector.onTouchEvent(ev);
|
return false;
|
||||||
return mSwipeDetector.isDraggingOrSettling();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean onTouchEvent(MotionEvent ev) {
|
|
||||||
if (mIgnoreTouch) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (mMainView.getNotificationInfo() == null) {
|
|
||||||
// The notification hasn't been populated yet.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return mSwipeDetector.onTouchEvent(ev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyNotificationInfos(final List<NotificationInfo> notificationInfos) {
|
public void applyNotificationInfos(final List<NotificationInfo> notificationInfos) {
|
||||||
|
mNotificationInfos.clear();
|
||||||
if (notificationInfos.isEmpty()) {
|
if (notificationInfos.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mNotificationInfos.addAll(notificationInfos);
|
||||||
|
|
||||||
NotificationInfo mainNotification = notificationInfos.get(0);
|
NotificationInfo mainNotification = notificationInfos.get(0);
|
||||||
mMainView.applyNotificationInfo(mainNotification, false);
|
mMainView.applyNotificationInfo(mainNotification, false);
|
||||||
|
|
||||||
for (int i = 1; i < notificationInfos.size(); i++) {
|
|
||||||
mFooter.addNotificationInfo(notificationInfos.get(i));
|
|
||||||
}
|
|
||||||
mFooter.commitNotificationInfos();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void trimNotifications(final List<String> notificationKeys) {
|
public void trimNotifications(final List<String> notificationKeys) {
|
||||||
boolean dismissedMainNotification = !notificationKeys.contains(
|
NotificationInfo currentMainNotificationInfo = mMainView.getNotificationInfo();
|
||||||
mMainView.getNotificationInfo().notificationKey);
|
boolean shouldUpdateMainNotification = !notificationKeys.contains(
|
||||||
if (dismissedMainNotification && !mAnimatingNextIcon) {
|
currentMainNotificationInfo.notificationKey);
|
||||||
// Animate the next icon into place as the new main notification.
|
|
||||||
mAnimatingNextIcon = true;
|
if (shouldUpdateMainNotification) {
|
||||||
mMainView.setContentVisibility(View.INVISIBLE);
|
int size = notificationKeys.size();
|
||||||
mMainView.setContentTranslation(0);
|
NotificationInfo nextNotification = null;
|
||||||
mIconView.getGlobalVisibleRect(sTempRect);
|
// We get the latest notification by finding the notification after the one that was
|
||||||
mFooter.animateFirstNotificationTo(sTempRect, (newMainNotification) -> {
|
// just dismissed.
|
||||||
if (newMainNotification != null) {
|
for (int i = 0; i < size; ++i) {
|
||||||
mMainView.applyNotificationInfo(newMainNotification, true);
|
if (currentMainNotificationInfo == mNotificationInfos.get(i) && i + 1 < size) {
|
||||||
mMainView.setContentVisibility(View.VISIBLE);
|
nextNotification = mNotificationInfos.get(i + 1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
mAnimatingNextIcon = false;
|
}
|
||||||
});
|
if (nextNotification != null) {
|
||||||
} else {
|
mMainView.applyNotificationInfo(nextNotification, true);
|
||||||
mFooter.trimNotifications(notificationKeys);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,19 +16,15 @@
|
|||||||
|
|
||||||
package com.android.launcher3.notification;
|
package com.android.launcher3.notification;
|
||||||
|
|
||||||
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
|
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DISMISSED;
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DISMISSED;
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.animation.AnimatorSet;
|
import android.animation.AnimatorSet;
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.ColorStateList;
|
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.graphics.drawable.RippleDrawable;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
@@ -40,19 +36,15 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
|
||||||
import com.android.launcher3.model.data.ItemInfo;
|
import com.android.launcher3.model.data.ItemInfo;
|
||||||
import com.android.launcher3.touch.BaseSwipeDetector;
|
|
||||||
import com.android.launcher3.touch.OverScroll;
|
|
||||||
import com.android.launcher3.touch.SingleAxisSwipeDetector;
|
import com.android.launcher3.touch.SingleAxisSwipeDetector;
|
||||||
import com.android.launcher3.util.Themes;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link android.widget.FrameLayout} that contains a single notification,
|
* A {@link android.widget.FrameLayout} that contains a single notification,
|
||||||
* e.g. icon + title + text.
|
* e.g. icon + title + text.
|
||||||
*/
|
*/
|
||||||
@TargetApi(Build.VERSION_CODES.N)
|
@TargetApi(Build.VERSION_CODES.N)
|
||||||
public class NotificationMainView extends FrameLayout implements SingleAxisSwipeDetector.Listener {
|
public class NotificationMainView extends FrameLayout {
|
||||||
|
|
||||||
private static final FloatProperty<NotificationMainView> CONTENT_TRANSLATION =
|
private static final FloatProperty<NotificationMainView> CONTENT_TRANSLATION =
|
||||||
new FloatProperty<NotificationMainView>("contentTranslation") {
|
new FloatProperty<NotificationMainView>("contentTranslation") {
|
||||||
@@ -70,8 +62,6 @@ public class NotificationMainView extends FrameLayout implements SingleAxisSwipe
|
|||||||
// This is used only to track the notification view, so that it can be properly logged.
|
// This is used only to track the notification view, so that it can be properly logged.
|
||||||
public static final ItemInfo NOTIFICATION_ITEM_INFO = new ItemInfo();
|
public static final ItemInfo NOTIFICATION_ITEM_INFO = new ItemInfo();
|
||||||
|
|
||||||
private final ObjectAnimator mContentTranslateAnimator;
|
|
||||||
|
|
||||||
private NotificationInfo mNotificationInfo;
|
private NotificationInfo mNotificationInfo;
|
||||||
private ViewGroup mTextAndBackground;
|
private ViewGroup mTextAndBackground;
|
||||||
private int mBackgroundColor;
|
private int mBackgroundColor;
|
||||||
@@ -82,7 +72,6 @@ public class NotificationMainView extends FrameLayout implements SingleAxisSwipe
|
|||||||
private SingleAxisSwipeDetector mSwipeDetector;
|
private SingleAxisSwipeDetector mSwipeDetector;
|
||||||
|
|
||||||
private final ColorDrawable mColorDrawable;
|
private final ColorDrawable mColorDrawable;
|
||||||
private final RippleDrawable mRippleDrawable;
|
|
||||||
|
|
||||||
public NotificationMainView(Context context) {
|
public NotificationMainView(Context context) {
|
||||||
this(context, null, 0);
|
this(context, null, 0);
|
||||||
@@ -95,11 +84,7 @@ public class NotificationMainView extends FrameLayout implements SingleAxisSwipe
|
|||||||
public NotificationMainView(Context context, AttributeSet attrs, int defStyle) {
|
public NotificationMainView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
|
|
||||||
mContentTranslateAnimator = ObjectAnimator.ofFloat(this, CONTENT_TRANSLATION, 0);
|
|
||||||
mColorDrawable = new ColorDrawable(Color.TRANSPARENT);
|
mColorDrawable = new ColorDrawable(Color.TRANSPARENT);
|
||||||
mRippleDrawable = new RippleDrawable(ColorStateList.valueOf(
|
|
||||||
Themes.getAttrColor(getContext(), android.R.attr.colorControlHighlight)),
|
|
||||||
mColorDrawable, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -118,7 +103,7 @@ public class NotificationMainView extends FrameLayout implements SingleAxisSwipe
|
|||||||
private void updateBackgroundColor(int color) {
|
private void updateBackgroundColor(int color) {
|
||||||
mBackgroundColor = color;
|
mBackgroundColor = color;
|
||||||
mColorDrawable.setColor(color);
|
mColorDrawable.setColor(color);
|
||||||
mTextAndBackground.setBackground(mRippleDrawable);
|
mTextAndBackground.setBackground(mColorDrawable);
|
||||||
if (mNotificationInfo != null) {
|
if (mNotificationInfo != null) {
|
||||||
mIconView.setBackground(mNotificationInfo.getIconForBackground(getContext(),
|
mIconView.setBackground(mNotificationInfo.getIconForBackground(getContext(),
|
||||||
mBackgroundColor));
|
mBackgroundColor));
|
||||||
@@ -140,10 +125,6 @@ public class NotificationMainView extends FrameLayout implements SingleAxisSwipe
|
|||||||
animatorSetOut.play(colors);
|
animatorSetOut.play(colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSwipeDetector(SingleAxisSwipeDetector swipeDetector) {
|
|
||||||
mSwipeDetector = swipeDetector;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the content of this view, animating it after a new icon shifts up if necessary.
|
* Sets the content of this view, animating it after a new icon shifts up if necessary.
|
||||||
*/
|
*/
|
||||||
@@ -182,11 +163,6 @@ public class NotificationMainView extends FrameLayout implements SingleAxisSwipe
|
|||||||
mIconView.setTranslationX(translation);
|
mIconView.setTranslationX(translation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContentVisibility(int visibility) {
|
|
||||||
mTextAndBackground.setVisibility(visibility);
|
|
||||||
mIconView.setVisibility(visibility);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NotificationInfo getNotificationInfo() {
|
public NotificationInfo getNotificationInfo() {
|
||||||
return mNotificationInfo;
|
return mNotificationInfo;
|
||||||
}
|
}
|
||||||
@@ -202,56 +178,4 @@ public class NotificationMainView extends FrameLayout implements SingleAxisSwipe
|
|||||||
mNotificationInfo.notificationKey);
|
mNotificationInfo.notificationKey);
|
||||||
launcher.getStatsLogManager().logger().log(LAUNCHER_NOTIFICATION_DISMISSED);
|
launcher.getStatsLogManager().logger().log(LAUNCHER_NOTIFICATION_DISMISSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SingleAxisSwipeDetector.Listener's
|
|
||||||
@Override
|
|
||||||
public void onDragStart(boolean start, float startDisplacement) { }
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onDrag(float displacement) {
|
|
||||||
setContentTranslation(canChildBeDismissed()
|
|
||||||
? displacement : OverScroll.dampedScroll(displacement, getWidth()));
|
|
||||||
mContentTranslateAnimator.cancel();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDragEnd(float velocity) {
|
|
||||||
final boolean willExit;
|
|
||||||
final float endTranslation;
|
|
||||||
final float startTranslation = mTextAndBackground.getTranslationX();
|
|
||||||
|
|
||||||
if (!canChildBeDismissed()) {
|
|
||||||
willExit = false;
|
|
||||||
endTranslation = 0;
|
|
||||||
} else if (mSwipeDetector.isFling(velocity)) {
|
|
||||||
willExit = true;
|
|
||||||
endTranslation = velocity < 0 ? - getWidth() : getWidth();
|
|
||||||
} else if (Math.abs(startTranslation) > getWidth() / 2) {
|
|
||||||
willExit = true;
|
|
||||||
endTranslation = (startTranslation < 0 ? -getWidth() : getWidth());
|
|
||||||
} else {
|
|
||||||
willExit = false;
|
|
||||||
endTranslation = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
long duration = BaseSwipeDetector.calculateDuration(velocity,
|
|
||||||
(endTranslation - startTranslation) / getWidth());
|
|
||||||
|
|
||||||
mContentTranslateAnimator.removeAllListeners();
|
|
||||||
mContentTranslateAnimator.setDuration(duration)
|
|
||||||
.setInterpolator(scrollInterpolatorForVelocity(velocity));
|
|
||||||
mContentTranslateAnimator.setFloatValues(startTranslation, endTranslation);
|
|
||||||
mContentTranslateAnimator.addListener(new AnimationSuccessListener() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationSuccess(Animator animator) {
|
|
||||||
mSwipeDetector.finishedScrolling();
|
|
||||||
if (willExit) {
|
|
||||||
onChildDismissed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mContentTranslateAnimator.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,14 +137,6 @@ public class PopupContainerWithArrow<T extends StatefulActivity<LauncherState>>
|
|||||||
> squaredTouchSlop(getContext());
|
> squaredTouchSlop(getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent ev) {
|
|
||||||
if (mNotificationItemView != null) {
|
|
||||||
return mNotificationItemView.onTouchEvent(ev) || super.onTouchEvent(ev);
|
|
||||||
}
|
|
||||||
return super.onTouchEvent(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isOfType(int type) {
|
protected boolean isOfType(int type) {
|
||||||
return (type & TYPE_ACTION_POPUP) != 0;
|
return (type & TYPE_ACTION_POPUP) != 0;
|
||||||
@@ -272,12 +264,6 @@ public class PopupContainerWithArrow<T extends StatefulActivity<LauncherState>>
|
|||||||
}
|
}
|
||||||
View.inflate(getContext(), R.layout.notification_content, mNotificationContainer);
|
View.inflate(getContext(), R.layout.notification_content, mNotificationContainer);
|
||||||
mNotificationItemView = new NotificationItemView(this, mNotificationContainer);
|
mNotificationItemView = new NotificationItemView(this, mNotificationContainer);
|
||||||
if (mNumNotifications == 1) {
|
|
||||||
mNotificationItemView.removeFooter();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mNotificationItemView.setFooterWidth(containerWidth);
|
|
||||||
}
|
|
||||||
updateNotificationHeader();
|
updateNotificationHeader();
|
||||||
}
|
}
|
||||||
int viewsToFlip = getChildCount();
|
int viewsToFlip = getChildCount();
|
||||||
@@ -462,8 +448,7 @@ public class PopupContainerWithArrow<T extends StatefulActivity<LauncherState>>
|
|||||||
ItemInfoWithIcon itemInfo = (ItemInfoWithIcon) mOriginalIcon.getTag();
|
ItemInfoWithIcon itemInfo = (ItemInfoWithIcon) mOriginalIcon.getTag();
|
||||||
DotInfo dotInfo = mLauncher.getDotInfoForItem(itemInfo);
|
DotInfo dotInfo = mLauncher.getDotInfoForItem(itemInfo);
|
||||||
if (mNotificationItemView != null && dotInfo != null) {
|
if (mNotificationItemView != null && dotInfo != null) {
|
||||||
mNotificationItemView.updateHeader(
|
mNotificationItemView.updateHeader(dotInfo.getNotificationCount());
|
||||||
dotInfo.getNotificationCount(), itemInfo.bitmap.color);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user