/*
* Copyright (C) 2010 mAPPn.Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mappn.gfan.common.widget;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import com.mappn.gfan.R;
/**
* Loading Animation Drawable for mAPPn android project.
*
* @author andrew.wang
* @version 0.0.2
*/
public class LoadingDrawable extends AnimationDrawable {
/**
* LoadingDrawable style -- SMALL
*
* (width: 54dp, height: 12dp)
*/
public static final int SIZE_SMALL = 0;
/**
* LoadingDrawable style -- MEDIUM
*
* (width: 90dp, height: 20dp)
*/
public static final int SIZE_MEDIUM = 1;
/**
* LoadingDrawable style -- LARGE
*
* (width: 180dp, height: 40dp)
*/
public static final int SIZE_LARGE = 2;
// default animation duration
private static final int DURATION = 200;
private static final int WIDTH_SMALL = 54;
private static final int HEIGHT_SMALL = 12;
private static final int WIDTH_MEDIUM = 90;
private static final int HEIGHT_MEDIUM = 20;
private static final int WIDTH_LARGE = 180;
private static final int HEIGHT_LARGE = 40;
private static final int BLOCK_NUMBER = 4;
// highlight color
private int color1;
// default color
private int color2;
// the default loading style is small
private int mLoadingStyle;
// the animation duration
private int mDuration;
/**
* The LoadingDrawable with default settings.<br>
* 1 --> size style is SMALL<br>
* 2 --> highlight color is "ffff9600"<br>
* 3 --> default color is "ffcdcdcd"<br>
* 4 --> background color is "Color.WHITE"<br>
* <br>
* If you want to customize your own style, please reference
* <pre>LoadingDrawable(int style, int highlightColor, int defaultColor, int backgroundColor)</pre>
*/
public LoadingDrawable(Context context) {
this(context, SIZE_SMALL, 0, 0, DURATION);
}
/**
* The LoadingDrawable with customize style.<br>
*
* @param style The size of loading drawable
* @param highlightColor The higlight color
* @param defaultColor The default color
* @param duration The animation duration of each frame
*/
public LoadingDrawable(Context context, int style, int highlightColor, int defaultColor, int duration) {
// init configuration info
mLoadingStyle = style;
if (highlightColor == 0) {
color1 = Color.parseColor("#80ff9600");
color2 = Color.parseColor("#30000000");
} else {
color1 = context.getResources().getColor(highlightColor);
color2 = context.getResources().getColor(defaultColor);
}
mDuration = duration;
final Resources res = context.getResources();
// repeat the animation
setOneShot(false);
float space = 0;
float halfWidth = 0;
float width = 0;
float lightHalfWidth = 0;
int totalWidth = 0;
int totalHeight = 0;
switch (mLoadingStyle) {
case SIZE_SMALL:
space = res.getDimension(R.dimen.space_small);
halfWidth = space / 2;
width = space;
lightHalfWidth = res.getDimension(R.dimen.space_small_h) / 2;
totalWidth = (int) res.getDimension(R.dimen.width_small);
totalHeight = (int) res.getDimension(R.dimen.height_small);
break;
case SIZE_MEDIUM:
space = res.getDimension(R.dimen.space_medium);
halfWidth = space / 2;
width = space;
lightHalfWidth = res.getDimension(R.dimen.space_medium_h) / 2;
totalWidth = (int) res.getDimension(R.dimen.width_medium);
totalHeight = (int) res.getDimension(R.dimen.height_medium);
break;
case SIZE_LARGE:
space = res.getDimension(R.dimen.space_large);
halfWidth = space / 2;
width = space;
lightHalfWidth = res.getDimension(R.dimen.space_large_h) / 2;
totalWidth = (int) res.getDimension(R.dimen.width_large);
totalHeight = (int) res.getDimension(R.dimen.height_large);
break;
}
Paint highlightColorPaint = new Paint();
highlightColorPaint.setColor(color1);
highlightColorPaint.setStyle(Style.FILL);
highlightColorPaint.setAntiAlias(true);
Paint normalColorPaint = new Paint();
normalColorPaint.setColor(color2);
normalColorPaint.setStyle(Style.FILL);
normalColorPaint.setAntiAlias(true);
Canvas canvas = new Canvas();
int frameIndex = 0;
while (frameIndex < 6) {
Bitmap frame = null;
try {
frame = Bitmap.createBitmap(totalWidth, totalHeight, Bitmap.Config.ARGB_4444);
} catch (OutOfMemoryError error) {
}
if (frame == null) {
continue;
}
canvas.setBitmap(frame);
canvas.drawColor(Color.TRANSPARENT);
int startPositionX = 0;
int startPositionY = totalHeight / 2;
int blockIndex = 0;
int drawIndex = frameIndex < 4 ? frameIndex : (3 - frameIndex % 3);
while (blockIndex < BLOCK_NUMBER) {
// try to draw 4 blocks on the bitmap
float left = 0;
float top = 0;
float right = 0;
float bottom = 0;
if (blockIndex == 0) {
startPositionX += (space + halfWidth);
} else {
startPositionX += (space + width);
}
Paint paint;
if (blockIndex == drawIndex) {
// current loading item is bigger
left = startPositionX - lightHalfWidth;
top = startPositionY - lightHalfWidth;
right = startPositionX + lightHalfWidth;
bottom = startPositionY + lightHalfWidth;
paint = highlightColorPaint;
} else {
// other item is default size
left = startPositionX - halfWidth;
top = startPositionY - halfWidth;
right = startPositionX + halfWidth;
bottom = startPositionY + halfWidth;
paint = normalColorPaint;
}
canvas.drawRect(left, top, right, bottom, paint);
blockIndex++;
}
frameIndex++;
canvas.save();
addFrame(new BitmapDrawable(frame), mDuration);
}
}
@Override
public int getMinimumHeight() {
switch (mLoadingStyle) {
case SIZE_SMALL:
return HEIGHT_SMALL;
case SIZE_MEDIUM:
return HEIGHT_MEDIUM;
case SIZE_LARGE:
return HEIGHT_LARGE;
default:
break;
}
return super.getMinimumHeight();
}
@Override
public int getMinimumWidth() {
switch (mLoadingStyle) {
case SIZE_SMALL:
return WIDTH_SMALL;
case SIZE_MEDIUM:
return WIDTH_MEDIUM;
case SIZE_LARGE:
return WIDTH_LARGE;
default:
break;
}
return super.getMinimumWidth();
}
}