├── faster_animation.jar
├── libs
└── android-support-v4.jar
├── res
├── drawable-xhdpi
│ ├── anim_1.jpg
│ ├── anim_2.jpg
│ ├── anim_3.jpg
│ ├── anim_4.jpg
│ ├── anim_5.jpg
│ ├── anim_6.jpg
│ ├── anim_7.jpg
│ ├── anim_8.jpg
│ └── ic_launcher.png
├── values
│ ├── strings.xml
│ └── styles.xml
├── drawable-hdpi
│ └── ic_launcher.png
├── drawable-mdpi
│ └── ic_launcher.png
├── values-v11
│ └── styles.xml
├── values-v14
│ └── styles.xml
└── layout
│ └── activity_example.xml
├── project.properties
├── proguard-project.txt
├── AndroidManifest.xml
├── src
└── com
│ └── tigerlee
│ └── libs
│ ├── activity
│ └── ExampleActivity.java
│ └── FasterAnimationsContainer.java
└── README.md
/faster_animation.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigerjj/FasterAnimationsContainer/HEAD/faster_animation.jar
--------------------------------------------------------------------------------
/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigerjj/FasterAnimationsContainer/HEAD/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/res/drawable-xhdpi/anim_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigerjj/FasterAnimationsContainer/HEAD/res/drawable-xhdpi/anim_1.jpg
--------------------------------------------------------------------------------
/res/drawable-xhdpi/anim_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigerjj/FasterAnimationsContainer/HEAD/res/drawable-xhdpi/anim_2.jpg
--------------------------------------------------------------------------------
/res/drawable-xhdpi/anim_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigerjj/FasterAnimationsContainer/HEAD/res/drawable-xhdpi/anim_3.jpg
--------------------------------------------------------------------------------
/res/drawable-xhdpi/anim_4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigerjj/FasterAnimationsContainer/HEAD/res/drawable-xhdpi/anim_4.jpg
--------------------------------------------------------------------------------
/res/drawable-xhdpi/anim_5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigerjj/FasterAnimationsContainer/HEAD/res/drawable-xhdpi/anim_5.jpg
--------------------------------------------------------------------------------
/res/drawable-xhdpi/anim_6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigerjj/FasterAnimationsContainer/HEAD/res/drawable-xhdpi/anim_6.jpg
--------------------------------------------------------------------------------
/res/drawable-xhdpi/anim_7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigerjj/FasterAnimationsContainer/HEAD/res/drawable-xhdpi/anim_7.jpg
--------------------------------------------------------------------------------
/res/drawable-xhdpi/anim_8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigerjj/FasterAnimationsContainer/HEAD/res/drawable-xhdpi/anim_8.jpg
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | FasterAnimationsContainer
4 |
5 |
6 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigerjj/FasterAnimationsContainer/HEAD/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigerjj/FasterAnimationsContainer/HEAD/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tigerjj/FasterAnimationsContainer/HEAD/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/res/layout/activity_example.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-19
15 | android.library=false
16 |
--------------------------------------------------------------------------------
/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
9 |
10 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/com/tigerlee/libs/activity/ExampleActivity.java:
--------------------------------------------------------------------------------
1 | package com.tigerlee.libs.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.widget.ImageView;
6 |
7 | import com.tigerlee.libs.FasterAnimationsContainer;
8 | import com.tigerlee.libs.R;
9 |
10 | public class ExampleActivity extends Activity {
11 |
12 | FasterAnimationsContainer mFasterAnimationsContainer;
13 | private static final int[] IMAGE_RESOURCES = { R.drawable.anim_1,
14 | R.drawable.anim_2, R.drawable.anim_3, R.drawable.anim_4,
15 | R.drawable.anim_5, R.drawable.anim_6, R.drawable.anim_7,
16 | R.drawable.anim_8 };
17 |
18 | private static final int ANIMATION_INTERVAL = 500;// 200ms
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_example);
24 | ImageView imageView = (ImageView) findViewById(R.id.imageview);
25 | mFasterAnimationsContainer = FasterAnimationsContainer
26 | .getInstance(imageView);
27 | mFasterAnimationsContainer.addAllFrames(IMAGE_RESOURCES,
28 | ANIMATION_INTERVAL);
29 | mFasterAnimationsContainer.start();
30 | }
31 |
32 | @Override
33 | protected void onDestroy() {
34 | super.onDestroy();
35 | mFasterAnimationsContainer.stop();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | FasterAnimationsContainer
2 | ============================
3 | FasterAnimationsContainer will help you to avoid from OutOfMemoryError. Android loads all the drawables at once, so animation with many frames causes this error. This class loads & sets and releases an image on background thread.
4 |
5 | Easy to implement
6 | -------------------
7 |
8 |
9 | ```java
10 | public class ExampleActivity extends Activity {
11 | FasterAnimationsContainer mFasterAnimationsContainer;
12 | private static final int[] IMAGE_RESOURCES = { R.drawable.anim_1,
13 | R.drawable.anim_2, R.drawable.anim_3, R.drawable.anim_4,
14 | R.drawable.anim_5, R.drawable.anim_6, R.drawable.anim_7,
15 | R.drawable.anim_8 };
16 |
17 | private static final int ANIMATION_INTERVAL = 500;// 500ms
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_example);
23 | ImageView imageView = (ImageView) findViewById(R.id.imageview);
24 | mFasterAnimationsContainer = FasterAnimationsContainer
25 | .getInstance(imageView);
26 | mFasterAnimationsContainer.addAllFrames(IMAGE_RESOURCES,
27 | ANIMATION_INTERVAL);
28 | mFasterAnimationsContainer.start();
29 | }
30 |
31 | @Override
32 | protected void onDestroy() {
33 | super.onDestroy();
34 | mFasterAnimationsContainer.stop();
35 | }
36 | }
37 | ```
38 |
--------------------------------------------------------------------------------
/src/com/tigerlee/libs/FasterAnimationsContainer.java:
--------------------------------------------------------------------------------
1 | package com.tigerlee.libs;
2 |
3 |
4 | import android.annotation.SuppressLint;
5 | import android.graphics.Bitmap;
6 | import android.graphics.BitmapFactory;
7 | import android.graphics.drawable.BitmapDrawable;
8 | import android.graphics.drawable.Drawable;
9 | import android.os.AsyncTask;
10 | import android.os.Build;
11 | import android.os.Handler;
12 | import android.widget.ImageView;
13 |
14 | import java.lang.ref.SoftReference;
15 | import java.util.ArrayList;
16 |
17 |
18 | public class FasterAnimationsContainer{
19 | private class AnimationFrame{
20 | private int mResourceId;
21 | private int mDuration;
22 | AnimationFrame(int resourceId, int duration){
23 | mResourceId = resourceId;
24 | mDuration = duration;
25 | }
26 | public int getResourceId() {
27 | return mResourceId;
28 | }
29 | public int getDuration() {
30 | return mDuration;
31 | }
32 | }
33 | private ArrayList mAnimationFrames; // list for all frames of animation
34 | private int mIndex; // index of current frame
35 |
36 | private boolean mShouldRun; // true if the animation should continue running. Used to stop the animation
37 | private boolean mIsRunning; // true if the animation prevents starting the animation twice
38 | private SoftReference mSoftReferenceImageView; // Used to prevent holding ImageView when it should be dead.
39 | private Handler mHandler; // Handler to communication with UIThread
40 |
41 | private Bitmap mRecycleBitmap; //Bitmap can recycle by inBitmap is SDK Version >=11
42 |
43 | // Listeners
44 | private OnAnimationStoppedListener mOnAnimationStoppedListener;
45 | private OnAnimationFrameChangedListener mOnAnimationFrameChangedListener;
46 |
47 | private FasterAnimationsContainer(ImageView imageView) {
48 | init(imageView);
49 | };
50 |
51 | // single instance procedures
52 | private static FasterAnimationsContainer sInstance;
53 |
54 | public static FasterAnimationsContainer getInstance(ImageView imageView) {
55 | if (sInstance == null)
56 | sInstance = new FasterAnimationsContainer(imageView);
57 | sInstance.mRecycleBitmap = null;
58 | return sInstance;
59 | }
60 |
61 | /**
62 | * initialize imageview and frames
63 | * @param imageView
64 | */
65 | public void init(ImageView imageView){
66 | mAnimationFrames = new ArrayList();
67 | mSoftReferenceImageView = new SoftReference(imageView);
68 |
69 | mHandler = new Handler();
70 | if(mIsRunning == true){
71 | stop();
72 | }
73 |
74 | mShouldRun = false;
75 | mIsRunning = false;
76 |
77 | mIndex = -1;
78 | }
79 |
80 | /**
81 | * add a frame of animation
82 | * @param index index of animation
83 | * @param resId resource id of drawable
84 | * @param interval milliseconds
85 | */
86 | public void addFrame(int index, int resId, int interval){
87 | mAnimationFrames.add(index, new AnimationFrame(resId, interval));
88 | }
89 |
90 | /**
91 | * add a frame of animation
92 | * @param resId resource id of drawable
93 | * @param interval milliseconds
94 | */
95 | public void addFrame(int resId, int interval){
96 | mAnimationFrames.add(new AnimationFrame(resId, interval));
97 | }
98 |
99 | /**
100 | * add all frames of animation
101 | * @param resId resource id of drawable
102 | * @param interval milliseconds
103 | */
104 | public void addAllFrames(int[] resIds, int interval){
105 | for(int resId : resIds){
106 | mAnimationFrames.add(new AnimationFrame(resId, interval));
107 | }
108 | }
109 |
110 | /**
111 | * remove a frame with index
112 | * @param index index of animation
113 | */
114 | public void removeFrame(int index){
115 | mAnimationFrames.remove(index);
116 | }
117 |
118 | /**
119 | * clear all frames
120 | */
121 | public void removeAllFrames(){
122 | mAnimationFrames.clear();
123 | }
124 |
125 | /**
126 | * change a frame of animation
127 | * @param index index of animation
128 | * @param resId resource id of drawable
129 | * @param interval milliseconds
130 | */
131 | public void replaceFrame(int index, int resId, int interval){
132 | mAnimationFrames.set(index, new AnimationFrame(resId, interval));
133 | }
134 |
135 | private AnimationFrame getNext() {
136 | mIndex++;
137 | if (mIndex >= mAnimationFrames.size())
138 | mIndex = 0;
139 | return mAnimationFrames.get(mIndex);
140 | }
141 |
142 | /**
143 | * Listener of animation to detect stopped
144 | *
145 | */
146 | public interface OnAnimationStoppedListener{
147 | public void onAnimationStopped();
148 | }
149 |
150 | /**
151 | * Listener of animation to get index
152 | *
153 | */
154 | public interface OnAnimationFrameChangedListener{
155 | public void onAnimationFrameChanged(int index);
156 | }
157 |
158 |
159 | /**
160 | * set a listener for OnAnimationStoppedListener
161 | * @param listener OnAnimationStoppedListener
162 | */
163 | public void setOnAnimationStoppedListener(OnAnimationStoppedListener listener){
164 | mOnAnimationStoppedListener = listener;
165 | }
166 |
167 | /**
168 | * set a listener for OnAnimationFrameChangedListener
169 | * @param listener OnAnimationFrameChangedListener
170 | */
171 | public void setOnAnimationFrameChangedListener(OnAnimationFrameChangedListener listener){
172 | mOnAnimationFrameChangedListener = listener;
173 | }
174 |
175 | /**
176 | * Starts the animation
177 | */
178 | public synchronized void start() {
179 | mShouldRun = true;
180 | if (mIsRunning)
181 | return;
182 | mHandler.post(new FramesSequenceAnimation());
183 | }
184 |
185 | /**
186 | * Stops the animation
187 | */
188 | public synchronized void stop() {
189 | mShouldRun = false;
190 | }
191 |
192 | private class FramesSequenceAnimation implements Runnable{
193 |
194 | @Override
195 | public void run() {
196 | ImageView imageView = mSoftReferenceImageView.get();
197 | if (!mShouldRun || imageView == null) {
198 | mIsRunning = false;
199 | if (mOnAnimationStoppedListener != null) {
200 | mOnAnimationStoppedListener.onAnimationStopped();
201 | }
202 | return;
203 | }
204 | mIsRunning = true;
205 |
206 | if (imageView.isShown()) {
207 | AnimationFrame frame = getNext();
208 | GetImageDrawableTask task = new GetImageDrawableTask(imageView);
209 | task.execute(frame.getResourceId());
210 | // TODO postDelayed after onPostExecute
211 | mHandler.postDelayed(this, frame.getDuration());
212 | }
213 | }
214 | }
215 |
216 | private class GetImageDrawableTask extends AsyncTask{
217 |
218 | private ImageView mImageView;
219 |
220 | public GetImageDrawableTask(ImageView imageView) {
221 | mImageView = imageView;
222 | }
223 |
224 | @SuppressLint("NewApi")
225 | @Override
226 | protected Drawable doInBackground(Integer... params) {
227 | if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB){
228 | return mImageView.getContext().getResources().getDrawable(params[0]);
229 | }
230 | BitmapFactory.Options options = new BitmapFactory.Options();
231 | options.inMutable = true;
232 | if (mRecycleBitmap != null)
233 | options.inBitmap = mRecycleBitmap;
234 | mRecycleBitmap = BitmapFactory.decodeResource(mImageView
235 | .getContext().getResources(), params[0], options);
236 | BitmapDrawable drawable = new BitmapDrawable(mImageView.getContext().getResources(),mRecycleBitmap);
237 | return drawable;
238 | }
239 |
240 | @Override
241 | protected void onPostExecute(Drawable result) {
242 | super.onPostExecute(result);
243 | if(result!=null) mImageView.setImageDrawable(result);
244 | if (mOnAnimationFrameChangedListener != null)
245 | mOnAnimationFrameChangedListener.onAnimationFrameChanged(mIndex);
246 | }
247 |
248 | }
249 | }
250 |
--------------------------------------------------------------------------------