Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2014 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.systemui.statusbar; |
| 18 | |
| 19 | import android.animation.Animator; |
| 20 | import android.animation.AnimatorListenerAdapter; |
| 21 | import android.animation.ValueAnimator; |
| 22 | import android.content.Context; |
| 23 | import android.graphics.Color; |
| 24 | import android.graphics.ColorFilter; |
| 25 | import android.graphics.ColorMatrix; |
| 26 | import android.graphics.ColorMatrixColorFilter; |
| 27 | import android.graphics.PorterDuff; |
| 28 | import android.graphics.PorterDuffColorFilter; |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 29 | import android.graphics.Rect; |
Jorim Jaggi | dacc924 | 2014-12-08 19:21:26 +0100 | [diff] [blame] | 30 | import android.graphics.drawable.Drawable; |
Selim Cinek | 8d6440d | 2015-10-22 13:00:05 -0700 | [diff] [blame] | 31 | import android.text.TextUtils; |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 32 | import android.view.MotionEvent; |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 33 | import android.view.View; |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 34 | import android.view.ViewConfiguration; |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 35 | import android.view.animation.AnimationUtils; |
| 36 | import android.view.animation.Interpolator; |
| 37 | import android.widget.ImageView; |
Selim Cinek | 8d6440d | 2015-10-22 13:00:05 -0700 | [diff] [blame] | 38 | import android.widget.TextView; |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 39 | |
| 40 | import com.android.systemui.R; |
| 41 | import com.android.systemui.ViewInvertHelper; |
| 42 | import com.android.systemui.statusbar.phone.NotificationPanelView; |
| 43 | |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 44 | import java.util.ArrayList; |
| 45 | |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 46 | /** |
| 47 | * Wraps a notification view inflated from a template. |
| 48 | */ |
| 49 | public class NotificationTemplateViewWrapper extends NotificationViewWrapper { |
| 50 | |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 51 | private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix(); |
| 52 | private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter( |
| 53 | 0, PorterDuff.Mode.SRC_ATOP); |
| 54 | private final int mIconDarkAlpha; |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 55 | private final int mIconDarkColor; |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 56 | private final Interpolator mLinearOutSlowInInterpolator; |
| 57 | |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 58 | private int mColor; |
Jorim Jaggi | dacc924 | 2014-12-08 19:21:26 +0100 | [diff] [blame] | 59 | private ViewInvertHelper mInvertHelper; |
| 60 | private ImageView mIcon; |
| 61 | protected ImageView mPicture; |
| 62 | |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 63 | /** |
| 64 | * Whether the icon needs to be forced grayscale when in dark mode. |
| 65 | */ |
Jorim Jaggi | 92df1f2 | 2014-12-16 19:44:41 +0100 | [diff] [blame] | 66 | private boolean mIconForceGraysaleWhenDark; |
Selim Cinek | 8d6440d | 2015-10-22 13:00:05 -0700 | [diff] [blame] | 67 | private TextView mSubText; |
| 68 | private TextView mInfoText; |
| 69 | private View mProfileBadge; |
Selim Cinek | 8d6440d | 2015-10-22 13:00:05 -0700 | [diff] [blame] | 70 | private View mThirdLine; |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 71 | private ImageView mExpandButton; |
| 72 | private View mNotificationHeader; |
| 73 | private View.OnClickListener mExpandClickListener; |
| 74 | private HeaderTouchListener mHeaderTouchListener; |
Jorim Jaggi | 92df1f2 | 2014-12-16 19:44:41 +0100 | [diff] [blame] | 75 | |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 76 | protected NotificationTemplateViewWrapper(Context ctx, View view) { |
| 77 | super(view); |
| 78 | mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha); |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 79 | mIconDarkColor = |
Alan Viverette | 4a357cd | 2015-03-18 18:37:18 -0700 | [diff] [blame] | 80 | ctx.getColor(R.color.doze_small_icon_background_color); |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 81 | mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(ctx, |
| 82 | android.R.interpolator.linear_out_slow_in); |
Jorim Jaggi | dacc924 | 2014-12-08 19:21:26 +0100 | [diff] [blame] | 83 | resolveViews(); |
| 84 | } |
| 85 | |
| 86 | private void resolveViews() { |
| 87 | View mainColumn = mView.findViewById(com.android.internal.R.id.notification_main_column); |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 88 | mInvertHelper = mainColumn != null |
| 89 | ? new ViewInvertHelper(mainColumn, NotificationPanelView.DOZE_ANIMATION_DURATION) |
| 90 | : null; |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 91 | mIcon = (ImageView) mView.findViewById(com.android.internal.R.id.icon); |
| 92 | mPicture = (ImageView) mView.findViewById(com.android.internal.R.id.right_icon); |
Selim Cinek | 8d6440d | 2015-10-22 13:00:05 -0700 | [diff] [blame] | 93 | mSubText = (TextView) mView.findViewById(com.android.internal.R.id.text); |
| 94 | mInfoText = (TextView) mView.findViewById(com.android.internal.R.id.info); |
| 95 | mProfileBadge = mView.findViewById(com.android.internal.R.id.profile_badge_line3); |
Selim Cinek | 8d6440d | 2015-10-22 13:00:05 -0700 | [diff] [blame] | 96 | mThirdLine = mView.findViewById(com.android.internal.R.id.line3); |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 97 | mExpandButton = (ImageView) mView.findViewById(com.android.internal.R.id.expand_button); |
| 98 | mColor = resolveColor(mExpandButton); |
| 99 | mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header); |
| 100 | // Post to make sure the parent lays out its children before we get their bounds |
| 101 | mHeaderTouchListener = new HeaderTouchListener(); |
| 102 | mExpandButton.post(new Runnable() { |
| 103 | @Override |
| 104 | public void run() { |
| 105 | // let's set up our touch regions |
| 106 | mHeaderTouchListener.bindTouchRects(mNotificationHeader, mIcon, mExpandButton); |
| 107 | } |
| 108 | }); |
Jorim Jaggi | 92df1f2 | 2014-12-16 19:44:41 +0100 | [diff] [blame] | 109 | |
| 110 | // If the icon already has a color filter, we assume that we already forced the icon to be |
| 111 | // white when we created the notification. |
Dan Sandler | 06433bd | 2015-02-25 13:20:39 -0500 | [diff] [blame] | 112 | final Drawable iconDrawable = mIcon != null ? mIcon.getDrawable() : null; |
| 113 | mIconForceGraysaleWhenDark = iconDrawable != null && iconDrawable.getColorFilter() != null; |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 114 | } |
| 115 | |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 116 | private int resolveColor(ImageView icon) { |
| 117 | if (icon != null && icon.getDrawable() != null) { |
| 118 | ColorFilter filter = icon.getDrawable().getColorFilter(); |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 119 | if (filter instanceof PorterDuffColorFilter) { |
| 120 | return ((PorterDuffColorFilter) filter).getColor(); |
| 121 | } |
| 122 | } |
| 123 | return 0; |
| 124 | } |
| 125 | |
| 126 | @Override |
Jorim Jaggi | dacc924 | 2014-12-08 19:21:26 +0100 | [diff] [blame] | 127 | public void notifyContentUpdated() { |
| 128 | super.notifyContentUpdated(); |
| 129 | |
| 130 | // Reinspect the notification. |
| 131 | resolveViews(); |
| 132 | } |
| 133 | |
| 134 | @Override |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 135 | public void setDark(boolean dark, boolean fade, long delay) { |
Jorim Jaggi | 394a5d6 | 2014-11-26 23:07:13 +0100 | [diff] [blame] | 136 | if (mInvertHelper != null) { |
| 137 | if (fade) { |
| 138 | mInvertHelper.fade(dark, delay); |
| 139 | } else { |
| 140 | mInvertHelper.update(dark); |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 141 | } |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 142 | } |
Jorim Jaggi | 394a5d6 | 2014-11-26 23:07:13 +0100 | [diff] [blame] | 143 | if (mIcon != null) { |
| 144 | if (fade) { |
| 145 | fadeIconColorFilter(mIcon, dark, delay); |
| 146 | fadeIconAlpha(mIcon, dark, delay); |
Jorim Jaggi | 92df1f2 | 2014-12-16 19:44:41 +0100 | [diff] [blame] | 147 | if (!mIconForceGraysaleWhenDark) { |
| 148 | fadeGrayscale(mIcon, dark, delay); |
| 149 | } |
Jorim Jaggi | 394a5d6 | 2014-11-26 23:07:13 +0100 | [diff] [blame] | 150 | } else { |
| 151 | updateIconColorFilter(mIcon, dark); |
| 152 | updateIconAlpha(mIcon, dark); |
Jorim Jaggi | 92df1f2 | 2014-12-16 19:44:41 +0100 | [diff] [blame] | 153 | if (!mIconForceGraysaleWhenDark) { |
| 154 | updateGrayscale(mIcon, dark); |
| 155 | } |
Jorim Jaggi | 394a5d6 | 2014-11-26 23:07:13 +0100 | [diff] [blame] | 156 | } |
| 157 | } |
| 158 | setPictureGrayscale(dark, fade, delay); |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 159 | } |
| 160 | |
| 161 | protected void setPictureGrayscale(boolean grayscale, boolean fade, long delay) { |
| 162 | if (mPicture != null) { |
| 163 | if (fade) { |
| 164 | fadeGrayscale(mPicture, grayscale, delay); |
| 165 | } else { |
| 166 | updateGrayscale(mPicture, grayscale); |
| 167 | } |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | private void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener, |
| 172 | boolean dark, long delay, Animator.AnimatorListener listener) { |
| 173 | float startIntensity = dark ? 0f : 1f; |
| 174 | float endIntensity = dark ? 1f : 0f; |
| 175 | ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity); |
| 176 | animator.addUpdateListener(updateListener); |
| 177 | animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION); |
| 178 | animator.setInterpolator(mLinearOutSlowInInterpolator); |
| 179 | animator.setStartDelay(delay); |
| 180 | if (listener != null) { |
| 181 | animator.addListener(listener); |
| 182 | } |
| 183 | animator.start(); |
| 184 | } |
| 185 | |
| 186 | private void fadeIconColorFilter(final ImageView target, boolean dark, long delay) { |
| 187 | startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() { |
| 188 | @Override |
| 189 | public void onAnimationUpdate(ValueAnimator animation) { |
| 190 | updateIconColorFilter(target, (Float) animation.getAnimatedValue()); |
| 191 | } |
| 192 | }, dark, delay, null /* listener */); |
| 193 | } |
| 194 | |
| 195 | private void fadeIconAlpha(final ImageView target, boolean dark, long delay) { |
| 196 | startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() { |
| 197 | @Override |
| 198 | public void onAnimationUpdate(ValueAnimator animation) { |
| 199 | float t = (float) animation.getAnimatedValue(); |
| 200 | target.setImageAlpha((int) (255 * (1f - t) + mIconDarkAlpha * t)); |
| 201 | } |
| 202 | }, dark, delay, null /* listener */); |
| 203 | } |
| 204 | |
| 205 | protected void fadeGrayscale(final ImageView target, final boolean dark, long delay) { |
| 206 | startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() { |
| 207 | @Override |
| 208 | public void onAnimationUpdate(ValueAnimator animation) { |
| 209 | updateGrayscaleMatrix((float) animation.getAnimatedValue()); |
| 210 | target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix)); |
| 211 | } |
| 212 | }, dark, delay, new AnimatorListenerAdapter() { |
| 213 | @Override |
| 214 | public void onAnimationEnd(Animator animation) { |
| 215 | if (!dark) { |
| 216 | target.setColorFilter(null); |
| 217 | } |
| 218 | } |
| 219 | }); |
| 220 | } |
| 221 | |
| 222 | private void updateIconColorFilter(ImageView target, boolean dark) { |
| 223 | updateIconColorFilter(target, dark ? 1f : 0f); |
| 224 | } |
| 225 | |
| 226 | private void updateIconColorFilter(ImageView target, float intensity) { |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 227 | int color = interpolateColor(mColor, mIconDarkColor, intensity); |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 228 | mIconColorFilter.setColor(color); |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 229 | Drawable iconDrawable = target.getDrawable(); |
Jorim Jaggi | dacc924 | 2014-12-08 19:21:26 +0100 | [diff] [blame] | 230 | |
Jorim Jaggi | 92df1f2 | 2014-12-16 19:44:41 +0100 | [diff] [blame] | 231 | // The background might be null for legacy notifications. Also, the notification might have |
| 232 | // been modified during the animation, so background might be null here. |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 233 | if (iconDrawable != null) { |
| 234 | iconDrawable.mutate().setColorFilter(mIconColorFilter); |
Jorim Jaggi | dacc924 | 2014-12-08 19:21:26 +0100 | [diff] [blame] | 235 | } |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 236 | } |
| 237 | |
| 238 | private void updateIconAlpha(ImageView target, boolean dark) { |
| 239 | target.setImageAlpha(dark ? mIconDarkAlpha : 255); |
| 240 | } |
| 241 | |
| 242 | protected void updateGrayscale(ImageView target, boolean dark) { |
| 243 | if (dark) { |
| 244 | updateGrayscaleMatrix(1f); |
| 245 | target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix)); |
| 246 | } else { |
| 247 | target.setColorFilter(null); |
| 248 | } |
| 249 | } |
| 250 | |
Selim Cinek | 8d6440d | 2015-10-22 13:00:05 -0700 | [diff] [blame] | 251 | @Override |
| 252 | public void setSubTextVisible(boolean visible) { |
| 253 | if (mSubText == null) { |
| 254 | return; |
| 255 | } |
| 256 | boolean subTextAvailable = !TextUtils.isEmpty(mSubText.getText()); |
| 257 | if (visible && subTextAvailable) { |
| 258 | mSubText.setVisibility(View.VISIBLE); |
| 259 | } else { |
| 260 | mSubText.setVisibility(View.GONE); |
| 261 | } |
| 262 | // TODO: figure out what to do with the number (same place as contentInfo) |
| 263 | // work profile badge. For now we hide it since it looks nicer. |
| 264 | boolean infoAvailable = !TextUtils.isEmpty(mInfoText.getText()); |
| 265 | if (visible && infoAvailable) { |
| 266 | mInfoText.setVisibility(View.VISIBLE); |
| 267 | } else { |
| 268 | mInfoText.setVisibility(View.GONE); |
| 269 | } |
| 270 | boolean showThirdLine = (visible && (infoAvailable || subTextAvailable)) |
| 271 | || mProfileBadge.getVisibility() == View.VISIBLE; |
Selim Cinek | 8d6440d | 2015-10-22 13:00:05 -0700 | [diff] [blame] | 272 | if (mThirdLine != null) { |
| 273 | if (showThirdLine) { |
| 274 | mThirdLine.setVisibility(View.VISIBLE); |
| 275 | } else { |
| 276 | mThirdLine.setVisibility(View.GONE); |
| 277 | } |
| 278 | } |
| 279 | } |
| 280 | |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 281 | @Override |
| 282 | public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) { |
| 283 | mExpandButton.setVisibility(expandable ? View.VISIBLE : View.GONE); |
| 284 | mNotificationHeader.setOnTouchListener(expandable ? mHeaderTouchListener : null); |
| 285 | mExpandClickListener = onClickListener; |
| 286 | } |
| 287 | |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 288 | private void updateGrayscaleMatrix(float intensity) { |
| 289 | mGrayscaleColorMatrix.setSaturation(1 - intensity); |
| 290 | } |
| 291 | |
| 292 | private static int interpolateColor(int source, int target, float t) { |
| 293 | int aSource = Color.alpha(source); |
| 294 | int rSource = Color.red(source); |
| 295 | int gSource = Color.green(source); |
| 296 | int bSource = Color.blue(source); |
| 297 | int aTarget = Color.alpha(target); |
| 298 | int rTarget = Color.red(target); |
| 299 | int gTarget = Color.green(target); |
| 300 | int bTarget = Color.blue(target); |
| 301 | return Color.argb( |
| 302 | (int) (aSource * (1f - t) + aTarget * t), |
| 303 | (int) (rSource * (1f - t) + rTarget * t), |
| 304 | (int) (gSource * (1f - t) + gTarget * t), |
| 305 | (int) (bSource * (1f - t) + bTarget * t)); |
| 306 | } |
Selim Cinek | 65b2e7c | 2015-10-26 14:11:31 -0700 | [diff] [blame] | 307 | |
| 308 | public class HeaderTouchListener implements View.OnTouchListener { |
| 309 | |
| 310 | private final ArrayList<Rect> mTouchRects = new ArrayList<>(); |
| 311 | private int mTouchSlop; |
| 312 | private boolean mTrackGesture; |
| 313 | private float mDownX; |
| 314 | private float mDownY; |
| 315 | |
| 316 | public HeaderTouchListener() { |
| 317 | } |
| 318 | |
| 319 | public void bindTouchRects(View parent, View icon, View expandButton) { |
| 320 | mTouchRects.clear(); |
| 321 | addRectAroundViewView(icon); |
| 322 | addRectAroundViewView(expandButton); |
| 323 | addInBetweenRect(parent); |
| 324 | mTouchSlop = ViewConfiguration.get(parent.getContext()).getScaledTouchSlop(); |
| 325 | } |
| 326 | |
| 327 | private void addInBetweenRect(View parent) { |
| 328 | final Rect r = new Rect(); |
| 329 | r.top = 0; |
| 330 | r.bottom = (int) (32 * parent.getResources().getDisplayMetrics().density); |
| 331 | Rect leftRect = mTouchRects.get(0); |
| 332 | r.left = leftRect.right; |
| 333 | Rect rightRect = mTouchRects.get(1); |
| 334 | r.right = rightRect.left; |
| 335 | mTouchRects.add(r); |
| 336 | } |
| 337 | |
| 338 | private void addRectAroundViewView(View view) { |
| 339 | final Rect r = getRectAroundView(view); |
| 340 | mTouchRects.add(r); |
| 341 | } |
| 342 | |
| 343 | private Rect getRectAroundView(View view) { |
| 344 | float size = 48 * view.getResources().getDisplayMetrics().density; |
| 345 | final Rect r = new Rect(); |
| 346 | r.top = (int) ((view.getTop() + view.getBottom()) / 2.0f - size / 2.0f); |
| 347 | r.bottom = (int) (r.top + size); |
| 348 | r.left = (int) ((view.getLeft() + view.getRight()) / 2.0f - size / 2.0f); |
| 349 | r.right = (int) (r.left + size); |
| 350 | return r; |
| 351 | } |
| 352 | |
| 353 | @Override |
| 354 | public boolean onTouch(View v, MotionEvent event) { |
| 355 | float x = event.getX(); |
| 356 | float y = event.getY(); |
| 357 | switch (event.getActionMasked() & MotionEvent.ACTION_MASK) { |
| 358 | case MotionEvent.ACTION_DOWN: |
| 359 | mTrackGesture = false; |
| 360 | if (isInside(x, y)) { |
| 361 | mTrackGesture = true; |
| 362 | return true; |
| 363 | } |
| 364 | break; |
| 365 | case MotionEvent.ACTION_MOVE: |
| 366 | if (mTrackGesture) { |
| 367 | if (Math.abs(mDownX - x) > mTouchSlop |
| 368 | || Math.abs(mDownY - y) > mTouchSlop) { |
| 369 | mTrackGesture = false; |
| 370 | } |
| 371 | } |
| 372 | break; |
| 373 | case MotionEvent.ACTION_UP: |
| 374 | if (mTrackGesture) { |
| 375 | mExpandClickListener.onClick(mNotificationHeader); |
| 376 | } |
| 377 | break; |
| 378 | } |
| 379 | return mTrackGesture; |
| 380 | } |
| 381 | |
| 382 | private boolean isInside(float x, float y) { |
| 383 | for (int i = 0; i < mTouchRects.size(); i++) { |
| 384 | Rect r = mTouchRects.get(i); |
| 385 | if (r.contains((int) x, (int) y)) { |
| 386 | mDownX = x; |
| 387 | mDownY = y; |
| 388 | return true; |
| 389 | } |
| 390 | } |
| 391 | return false; |
| 392 | } |
| 393 | } |
Jorim Jaggi | 4e857f4 | 2014-11-17 19:14:04 +0100 | [diff] [blame] | 394 | } |