1/*
2 * Copyright (C) 2008 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
17package com.android.systemui.statusbar;
18
19import android.content.Context;
20import android.content.res.TypedArray;
21import android.graphics.drawable.AnimationDrawable;
22import android.graphics.drawable.Drawable;
23import android.util.AttributeSet;
24import android.view.View;
25import android.widget.ImageView;
26import android.widget.RemoteViews.RemoteView;
27
28import com.android.systemui.R;
29
30@RemoteView
31public class AnimatedImageView extends ImageView {
32    private final boolean mHasOverlappingRendering;
33    AnimationDrawable mAnim;
34    boolean mAttached;
35    private boolean mAllowAnimation = true;
36
37    // Tracks the last image that was set, so that we don't refresh the image if it is exactly
38    // the same as the previous one. If this is a resid, we track that. If it's a drawable, we
39    // track the hashcode of the drawable.
40    int mDrawableId;
41
42    public AnimatedImageView(Context context) {
43        this(context, null);
44    }
45
46    public AnimatedImageView(Context context, AttributeSet attrs) {
47        super(context, attrs);
48        TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
49                R.styleable.AnimatedImageView, 0, 0);
50
51        try {
52            // Default to true, which is what View.java defaults toA
53            mHasOverlappingRendering = a.getBoolean(
54                    R.styleable.AnimatedImageView_hasOverlappingRendering, true);
55        } finally {
56            a.recycle();
57        }
58    }
59
60    public void setAllowAnimation(boolean allowAnimation) {
61        if (mAllowAnimation != allowAnimation) {
62            mAllowAnimation = allowAnimation;
63            updateAnim();
64            if (!mAllowAnimation && mAnim != null) {
65                // Reset drawable such that we show the first frame whenever we're not animating.
66                mAnim.setVisible(getVisibility() == VISIBLE, true /* restart */);
67            }
68        }
69    }
70
71    private void updateAnim() {
72        Drawable drawable = getDrawable();
73        if (mAttached && mAnim != null) {
74            mAnim.stop();
75        }
76        if (drawable instanceof AnimationDrawable) {
77            mAnim = (AnimationDrawable) drawable;
78            if (isShown() && mAllowAnimation) {
79                mAnim.start();
80            }
81        } else {
82            mAnim = null;
83        }
84    }
85
86    @Override
87    public void setImageDrawable(Drawable drawable) {
88        if (drawable != null) {
89            if (mDrawableId == drawable.hashCode()) return;
90
91            mDrawableId = drawable.hashCode();
92        } else {
93            mDrawableId = 0;
94        }
95        super.setImageDrawable(drawable);
96        updateAnim();
97    }
98
99    @Override
100    @android.view.RemotableViewMethod
101    public void setImageResource(int resid) {
102        if (mDrawableId == resid) return;
103
104        mDrawableId = resid;
105        super.setImageResource(resid);
106        updateAnim();
107    }
108
109    @Override
110    public void onAttachedToWindow() {
111        super.onAttachedToWindow();
112        mAttached = true;
113        updateAnim();
114    }
115
116    @Override
117    public void onDetachedFromWindow() {
118        super.onDetachedFromWindow();
119        if (mAnim != null) {
120            mAnim.stop();
121        }
122        mAttached = false;
123    }
124
125    @Override
126    protected void onVisibilityChanged(View changedView, int vis) {
127        super.onVisibilityChanged(changedView, vis);
128        if (mAnim != null) {
129            if (isShown() && mAllowAnimation) {
130                mAnim.start();
131            } else {
132                mAnim.stop();
133            }
134        }
135    }
136
137    @Override
138    public boolean hasOverlappingRendering() {
139        return mHasOverlappingRendering;
140    }
141}
142
143