Home | History | Annotate | Download | only in statusbar
      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.content.Context;
     20 import android.content.res.ColorStateList;
     21 import android.graphics.Canvas;
     22 import android.graphics.ColorFilter;
     23 import android.graphics.PorterDuff;
     24 import android.graphics.drawable.Drawable;
     25 import android.graphics.drawable.RippleDrawable;
     26 import android.util.AttributeSet;
     27 import android.view.View;
     28 
     29 /**
     30  * A view that can be used for both the dimmed and normal background of an notification.
     31  */
     32 public class NotificationBackgroundView extends View {
     33 
     34     private Drawable mBackground;
     35     private int mClipTopAmount;
     36     private int mActualHeight;
     37     private int mClipBottomAmount;
     38     private int mTintColor;
     39 
     40     public NotificationBackgroundView(Context context, AttributeSet attrs) {
     41         super(context, attrs);
     42     }
     43 
     44     @Override
     45     protected void onDraw(Canvas canvas) {
     46         draw(canvas, mBackground);
     47     }
     48 
     49     private void draw(Canvas canvas, Drawable drawable) {
     50         int bottom = mActualHeight - mClipBottomAmount;
     51         if (drawable != null && bottom > mClipTopAmount) {
     52             drawable.setBounds(0, mClipTopAmount, getWidth(), bottom);
     53             drawable.draw(canvas);
     54         }
     55     }
     56 
     57     @Override
     58     protected boolean verifyDrawable(Drawable who) {
     59         return super.verifyDrawable(who) || who == mBackground;
     60     }
     61 
     62     @Override
     63     protected void drawableStateChanged() {
     64         drawableStateChanged(mBackground);
     65     }
     66 
     67     private void drawableStateChanged(Drawable d) {
     68         if (d != null && d.isStateful()) {
     69             d.setState(getDrawableState());
     70         }
     71     }
     72 
     73     @Override
     74     public void drawableHotspotChanged(float x, float y) {
     75         if (mBackground != null) {
     76             mBackground.setHotspot(x, y);
     77         }
     78     }
     79 
     80     /**
     81      * Sets a background drawable. As we need to change our bounds independently of layout, we need
     82      * the notion of a background independently of the regular View background..
     83      */
     84     public void setCustomBackground(Drawable background) {
     85         if (mBackground != null) {
     86             mBackground.setCallback(null);
     87             unscheduleDrawable(mBackground);
     88         }
     89         mBackground = background;
     90         if (mBackground != null) {
     91             mBackground.setCallback(this);
     92             setTint(mTintColor);
     93         }
     94         if (mBackground instanceof RippleDrawable) {
     95             ((RippleDrawable) mBackground).setForceSoftware(true);
     96         }
     97         invalidate();
     98     }
     99 
    100     public void setCustomBackground(int drawableResId) {
    101         final Drawable d = mContext.getDrawable(drawableResId);
    102         setCustomBackground(d);
    103     }
    104 
    105     public void setTint(int tintColor) {
    106         if (tintColor != 0) {
    107             mBackground.setColorFilter(tintColor, PorterDuff.Mode.SRC_ATOP);
    108         } else {
    109             mBackground.clearColorFilter();
    110         }
    111         mTintColor = tintColor;
    112         invalidate();
    113     }
    114 
    115     public void setActualHeight(int actualHeight) {
    116         mActualHeight = actualHeight;
    117         invalidate();
    118     }
    119 
    120     public int getActualHeight() {
    121         return mActualHeight;
    122     }
    123 
    124     public void setClipTopAmount(int clipTopAmount) {
    125         mClipTopAmount = clipTopAmount;
    126         invalidate();
    127     }
    128 
    129     public void setClipBottomAmount(int clipBottomAmount) {
    130         mClipBottomAmount = clipBottomAmount;
    131         invalidate();
    132     }
    133 
    134     @Override
    135     public boolean hasOverlappingRendering() {
    136 
    137         // Prevents this view from creating a layer when alpha is animating.
    138         return false;
    139     }
    140 
    141     public void setState(int[] drawableState) {
    142         mBackground.setState(drawableState);
    143     }
    144 
    145     public void setRippleColor(int color) {
    146         if (mBackground instanceof RippleDrawable) {
    147             RippleDrawable ripple = (RippleDrawable) mBackground;
    148             ripple.setColor(ColorStateList.valueOf(color));
    149         }
    150     }
    151 
    152     public void setDrawableAlpha(int drawableAlpha) {
    153         mBackground.setAlpha(drawableAlpha);
    154     }
    155 }
    156