OSDN Git Service

5e8e2c76831fffb0d8bfcc3f28fada26247ccb4a
[android-x86/packages-apps-Launcher3.git] / src / com / android / launcher3 / notification / NotificationItemView.java
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.launcher3.notification;
18
19 import android.animation.Animator;
20 import android.app.Notification;
21 import android.content.Context;
22 import android.graphics.Rect;
23 import android.support.annotation.Nullable;
24 import android.util.AttributeSet;
25 import android.view.MotionEvent;
26 import android.view.View;
27 import android.widget.FrameLayout;
28 import android.widget.TextView;
29
30 import com.android.launcher3.ItemInfo;
31 import com.android.launcher3.R;
32 import com.android.launcher3.anim.PillHeightRevealOutlineProvider;
33 import com.android.launcher3.graphics.IconPalette;
34 import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
35 import com.android.launcher3.popup.PopupItemView;
36 import com.android.launcher3.userevent.nano.LauncherLogProto;
37
38 import java.util.List;
39
40 /**
41  * A {@link FrameLayout} that contains a header, main view and a footer.
42  * The main view contains the icon and text (title + subtext) of the first notification.
43  * The footer contains: A list of just the icons of all the notifications past the first one.
44  * @see NotificationFooterLayout
45  */
46 public class NotificationItemView extends PopupItemView implements LogContainerProvider {
47
48     private static final Rect sTempRect = new Rect();
49
50     private TextView mHeaderCount;
51     private NotificationMainView mMainView;
52     private NotificationFooterLayout mFooter;
53     private SwipeHelper mSwipeHelper;
54     private boolean mAnimatingNextIcon;
55     private int mNotificationHeaderTextColor = Notification.COLOR_DEFAULT;
56
57     public NotificationItemView(Context context) {
58         this(context, null, 0);
59     }
60
61     public NotificationItemView(Context context, AttributeSet attrs) {
62         this(context, attrs, 0);
63     }
64
65     public NotificationItemView(Context context, AttributeSet attrs, int defStyle) {
66         super(context, attrs, defStyle);
67     }
68
69     @Override
70     protected void onFinishInflate() {
71         super.onFinishInflate();
72         mHeaderCount = (TextView) findViewById(R.id.notification_count);
73         mMainView = (NotificationMainView) findViewById(R.id.main_view);
74         mFooter = (NotificationFooterLayout) findViewById(R.id.footer);
75         mSwipeHelper = new SwipeHelper(SwipeHelper.X, mMainView, getContext());
76         mSwipeHelper.setDisableHardwareLayers(true);
77     }
78
79     public Animator animateHeightRemoval(int heightToRemove) {
80         final int newHeight = getHeight() - heightToRemove;
81         return new PillHeightRevealOutlineProvider(mPillRect,
82                 getBackgroundRadius(), newHeight).createRevealAnimator(this, true /* isReversed */);
83     }
84
85     public void updateHeader(int notificationCount, @Nullable IconPalette palette) {
86         mHeaderCount.setText(notificationCount <= 1 ? "" : String.valueOf(notificationCount));
87         if (palette != null) {
88             if (mNotificationHeaderTextColor == Notification.COLOR_DEFAULT) {
89                 mNotificationHeaderTextColor =
90                         IconPalette.resolveContrastColor(getContext(), palette.dominantColor,
91                             getResources().getColor(R.color.notification_header_background_color));
92             }
93             mHeaderCount.setTextColor(mNotificationHeaderTextColor);
94         }
95     }
96
97     @Override
98     public boolean onInterceptTouchEvent(MotionEvent ev) {
99         if (mMainView.getNotificationInfo() == null) {
100             // The notification hasn't been populated yet.
101             return false;
102         }
103         getParent().requestDisallowInterceptTouchEvent(true);
104         return mSwipeHelper.onInterceptTouchEvent(ev);
105     }
106
107     @Override
108     public boolean onTouchEvent(MotionEvent ev) {
109         if (mMainView.getNotificationInfo() == null) {
110             // The notification hasn't been populated yet.
111             return false;
112         }
113         return mSwipeHelper.onTouchEvent(ev) || super.onTouchEvent(ev);
114     }
115
116     public void applyNotificationInfos(final List<NotificationInfo> notificationInfos) {
117         if (notificationInfos.isEmpty()) {
118             return;
119         }
120
121         NotificationInfo mainNotification = notificationInfos.get(0);
122         mMainView.applyNotificationInfo(mainNotification, mIconView);
123
124         for (int i = 1; i < notificationInfos.size(); i++) {
125             mFooter.addNotificationInfo(notificationInfos.get(i));
126         }
127         mFooter.commitNotificationInfos();
128     }
129
130     public void trimNotifications(final List<String> notificationKeys) {
131         boolean dismissedMainNotification = !notificationKeys.contains(
132                 mMainView.getNotificationInfo().notificationKey);
133         if (dismissedMainNotification && !mAnimatingNextIcon) {
134             // Animate the next icon into place as the new main notification.
135             mAnimatingNextIcon = true;
136             mMainView.setVisibility(INVISIBLE);
137             mMainView.setTranslationX(0);
138             mIconView.getGlobalVisibleRect(sTempRect);
139             mFooter.animateFirstNotificationTo(sTempRect,
140                     new NotificationFooterLayout.IconAnimationEndListener() {
141                 @Override
142                 public void onIconAnimationEnd(NotificationInfo newMainNotification) {
143                     if (newMainNotification != null) {
144                         mMainView.applyNotificationInfo(newMainNotification, mIconView, true);
145                         mMainView.setVisibility(VISIBLE);
146                     }
147                     mAnimatingNextIcon = false;
148                 }
149             });
150         } else {
151             mFooter.trimNotifications(notificationKeys);
152         }
153     }
154
155     @Override
156     public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
157             LauncherLogProto.Target targetParent) {
158         target.itemType = LauncherLogProto.ItemType.NOTIFICATION;
159         targetParent.containerType = LauncherLogProto.ContainerType.DEEPSHORTCUTS;
160     }
161 }