• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DISMISSED;
20 
21 import android.animation.AnimatorSet;
22 import android.animation.ObjectAnimator;
23 import android.animation.ValueAnimator;
24 import android.annotation.TargetApi;
25 import android.content.Context;
26 import android.graphics.Color;
27 import android.graphics.drawable.ColorDrawable;
28 import android.os.Build;
29 import android.text.TextUtils;
30 import android.util.AttributeSet;
31 import android.util.FloatProperty;
32 import android.view.View;
33 import android.view.ViewGroup;
34 import android.widget.FrameLayout;
35 import android.widget.TextView;
36 
37 import com.android.launcher3.Launcher;
38 import com.android.launcher3.R;
39 import com.android.launcher3.model.data.ItemInfo;
40 import com.android.launcher3.touch.SingleAxisSwipeDetector;
41 
42 /**
43  * A {@link android.widget.FrameLayout} that contains a single notification,
44  * e.g. icon + title + text.
45  */
46 @TargetApi(Build.VERSION_CODES.N)
47 public class NotificationMainView extends FrameLayout {
48 
49     private static final FloatProperty<NotificationMainView> CONTENT_TRANSLATION =
50             new FloatProperty<NotificationMainView>("contentTranslation") {
51         @Override
52         public void setValue(NotificationMainView view, float v) {
53             view.setContentTranslation(v);
54         }
55 
56         @Override
57         public Float get(NotificationMainView view) {
58             return view.mTextAndBackground.getTranslationX();
59         }
60     };
61 
62     // This is used only to track the notification view, so that it can be properly logged.
63     public static final ItemInfo NOTIFICATION_ITEM_INFO = new ItemInfo();
64 
65     private NotificationInfo mNotificationInfo;
66     private ViewGroup mTextAndBackground;
67     private int mBackgroundColor;
68     private TextView mTitleView;
69     private TextView mTextView;
70     private View mIconView;
71 
72     private SingleAxisSwipeDetector mSwipeDetector;
73 
74     private final ColorDrawable mColorDrawable;
75 
NotificationMainView(Context context)76     public NotificationMainView(Context context) {
77         this(context, null, 0);
78     }
79 
NotificationMainView(Context context, AttributeSet attrs)80     public NotificationMainView(Context context, AttributeSet attrs) {
81         this(context, attrs, 0);
82     }
83 
NotificationMainView(Context context, AttributeSet attrs, int defStyle)84     public NotificationMainView(Context context, AttributeSet attrs, int defStyle) {
85         super(context, attrs, defStyle);
86 
87         mColorDrawable = new ColorDrawable(Color.TRANSPARENT);
88     }
89 
90     @Override
onFinishInflate()91     protected void onFinishInflate() {
92         super.onFinishInflate();
93 
94         mTextAndBackground = findViewById(R.id.text_and_background);
95         mTitleView = mTextAndBackground.findViewById(R.id.title);
96         mTextView = mTextAndBackground.findViewById(R.id.text);
97         mIconView = findViewById(R.id.popup_item_icon);
98 
99         ColorDrawable colorBackground = (ColorDrawable) mTextAndBackground.getBackground();
100         updateBackgroundColor(colorBackground.getColor());
101     }
102 
updateBackgroundColor(int color)103     private void updateBackgroundColor(int color) {
104         mBackgroundColor = color;
105         mColorDrawable.setColor(color);
106         mTextAndBackground.setBackground(mColorDrawable);
107         if (mNotificationInfo != null) {
108             mIconView.setBackground(mNotificationInfo.getIconForBackground(getContext(),
109                     mBackgroundColor));
110         }
111     }
112 
113     /**
114      * Animates the background color to a new color.
115      * @param color The color to change to.
116      * @param animatorSetOut The AnimatorSet where we add the color animator to.
117      */
updateBackgroundColor(int color, AnimatorSet animatorSetOut)118     public void updateBackgroundColor(int color, AnimatorSet animatorSetOut) {
119         int oldColor = mBackgroundColor;
120         ValueAnimator colors = ValueAnimator.ofArgb(oldColor, color);
121         colors.addUpdateListener(valueAnimator -> {
122             int newColor = (int) valueAnimator.getAnimatedValue();
123             updateBackgroundColor(newColor);
124         });
125         animatorSetOut.play(colors);
126     }
127 
128     /**
129      * Sets the content of this view, animating it after a new icon shifts up if necessary.
130      */
applyNotificationInfo(NotificationInfo mainNotification, boolean animate)131     public void applyNotificationInfo(NotificationInfo mainNotification, boolean animate) {
132         mNotificationInfo = mainNotification;
133         NotificationListener listener = NotificationListener.getInstanceIfConnected();
134         if (listener != null) {
135             listener.setNotificationsShown(new String[] {mNotificationInfo.notificationKey});
136         }
137         CharSequence title = mNotificationInfo.title;
138         CharSequence text = mNotificationInfo.text;
139         if (!TextUtils.isEmpty(title) && !TextUtils.isEmpty(text)) {
140             mTitleView.setText(title.toString());
141             mTextView.setText(text.toString());
142         } else {
143             mTitleView.setMaxLines(2);
144             mTitleView.setText(TextUtils.isEmpty(title) ? text.toString() : title.toString());
145             mTextView.setVisibility(GONE);
146         }
147         mIconView.setBackground(mNotificationInfo.getIconForBackground(getContext(),
148                 mBackgroundColor));
149         if (mNotificationInfo.intent != null) {
150             setOnClickListener(mNotificationInfo);
151         }
152         setContentTranslation(0);
153         // Add a stub ItemInfo so that logging populates the correct container and item types
154         // instead of DEFAULT_CONTAINERTYPE and DEFAULT_ITEMTYPE, respectively.
155         setTag(NOTIFICATION_ITEM_INFO);
156         if (animate) {
157             ObjectAnimator.ofFloat(mTextAndBackground, ALPHA, 0, 1).setDuration(150).start();
158         }
159     }
160 
setContentTranslation(float translation)161     public void setContentTranslation(float translation) {
162         mTextAndBackground.setTranslationX(translation);
163         mIconView.setTranslationX(translation);
164     }
165 
getNotificationInfo()166     public NotificationInfo getNotificationInfo() {
167         return mNotificationInfo;
168     }
169 
170 
canChildBeDismissed()171     public boolean canChildBeDismissed() {
172         return mNotificationInfo != null && mNotificationInfo.dismissable;
173     }
174 
onChildDismissed()175     public void onChildDismissed() {
176         Launcher launcher = Launcher.getLauncher(getContext());
177         launcher.getPopupDataProvider().cancelNotification(
178                 mNotificationInfo.notificationKey);
179         launcher.getStatsLogManager().logger().log(LAUNCHER_NOTIFICATION_DISMISSED);
180     }
181 }
182