/**
* 文 件 名: MT_BubbleTextView.java
* 描 述: BubbleTextView的扩展类,实现图标倒影到绘制,抖动
* 版 权: Copyright (c)2010-2011 motone All Rights Reserved.
* 公 司: 摩通科技
* 作 者: 魏景春 黄悦
* 版 本: 1.0
* 创建时间: 2011-1-19
*
* 修改历史:
* 时间 作者 版本 描述
* ------------------------------------------------------------------
* 2011-1-19 魏景春 1.0 1.0 Version
*/
package com.mogoo.launcher2;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Rect;
import android.graphics.Bitmap.Config;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import com.mogoo.launcher.R;
import com.mogoo.launcher2.config.Mogoo_GlobalConfig;
import com.mogoo.launcher2.utils.Mogoo_BitmapCache;
import com.mogoo.launcher2.utils.Mogoo_BitmapUtils;
import com.mogoo.launcher2.utils.Mogoo_DialogUtils;
public class Mogoo_BubbleTextView extends BubbleTextView implements Cloneable {
private static final String TAG = "Mogoo_BubbleTextView" ;
// 显示图标倒影标志
private boolean reflection = false;
private Bitmap iconReflection;
private Bitmap iconWithoutReflection;
// 抖动标志
protected boolean mVibration = false;
// 图标顺时针旋转标志
private boolean clockWiseRotate = true;
// 抖动帧数组
private Bitmap[] vibrationBitmaps;
// 删除图标
protected Bitmap delIcon;
// 计数图标
protected Bitmap countIcon;
private int frameIndex;
private int frameCount;
private int leftLimit;
private int rightLimit;
private Paint paint;
private Context mContext;
private boolean isClicked = false;
private static final int POST_START_TIME_LIMIT = 3;
private long lastInvalTime = 0;
private long keyDownTime;
private int downX;
private int downY;
private final static int DRAG_RANGE = 10;
private final static long DELAY_TIME_DRAG = 200;
protected boolean passTouchEvent = false;
public Mogoo_BubbleTextView(Context context) {
this(context, null);
}
public Mogoo_BubbleTextView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
init();
}
public Mogoo_BubbleTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
@Override
public void draw(Canvas canvas) {
if (!mVibration) {
drawReflection(canvas);
super.draw(canvas);
}
// 抖动描绘
drawVibrateIcon(canvas);
// 计数器描绘
if (!mVibration) {
drawCountIcon(canvas);
}
canvas.save();
}
public void setIconWithoutReflection() {
if (iconWithoutReflection == null) {
if (reflection) {
reflection = false;
if (!isDrawingCacheEnabled() && vibrationBitmaps == null) {
setDrawingCacheEnabled(true);
}
Bitmap bitmap = getDrawingCache();
if (bitmap != null) {
iconWithoutReflection = bitmap.copy(Config.ARGB_8888, false);
}
reflection = true;
invalidate();
}
}
}
public void setVibrationBitmaps(Bitmap[] vibrationBitmaps) {
this.vibrationBitmaps = vibrationBitmaps;
}
/**
* 设置图标是否显示倒影 @ author: 魏景春
*
* @param reflection 显示倒影标志
*/
public void setReflection(boolean reflection) {
this.reflection = reflection;
}
public void setIconReflection(Bitmap bitmap) {
if (bitmap == null && iconReflection != null) {
iconReflection.isRecycled();
}
iconReflection = bitmap;
}
/**
* 抖动标志获取 @ author: 黄悦
*
* @return
*/
public boolean isVibration() {
return mVibration;
}
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
int eventX = (int) event.getX();
int eventY = (int) event.getY();
if(!passTouchEvent){
switch (action) {
case MotionEvent.ACTION_MOVE:
if (Math.abs(System.currentTimeMillis() - keyDownTime) < DELAY_TIME_DRAG || isOverRange(eventX, eventY)) {
break;
}
if (mVibration) {
float x = event.getX();
float y = event.getY();
super.performLongClick();
return true;
}
break;
case MotionEvent.ACTION_DOWN:
keyDownTime = System.currentTimeMillis();
downX = (int) event.getX();
downY = (int) event.getY();
if (mVibration && delIcon != null && downX >= 0 && downX <= delIcon.getWidth() && downY >= 0
&& downY <= delIcon.getHeight()) {
Mogoo_DialogUtils.showDelDialog(getContext(), (ShortcutInfo) getTag());
}
break;
}
}
return super.onTouchEvent(event);
}
private boolean isOverRange(int x, int y){
return Math.sqrt(Math.pow(x - downX, 2) + Math.pow(y - downY, 2)) > DRAG_RANGE;
}
/**
* 删除按键点击 @ author: 黄悦
*/
// public boolean onTouch(View v, MotionEvent event) {
//
// // if (mVibration && MotionEvent.ACTION_DOWN == action) {
// // float x = event.getX();
// // float y = event.getY();
// //
// // if (delIcon != null && x >= 0 && x <= delIcon.getWidth() && y >= 0
// // && y <= delIcon.getHeight()) {
// // MT_DialogUtils.showDelDialog(getContext(), (ShortcutInfo) getTag());
// // } else {
// // super.performLongClick();
// // }
// //
// // return true;
// // }
// //
// // return false;
// }
/**
* 返回无倾角图标 @ author: 黄悦
*
* @return
*/
public Bitmap getZeroAngleFrame() {
if (this.reflection && iconWithoutReflection != null) {
return iconWithoutReflection;
}
return null;
}
public void postInvalidate() {
super.postInvalidate();
}
/**
* 启动图标抖动 @ author: 黄悦
*
* @param cache
*/
public void startVibrate(Mogoo_BitmapCache cache, int startFrameIndex) {
startVibrate(cache, startFrameIndex, 0, false);
}
/**
* 启动图标抖动 @ author: 曾少彬
*
* @param cache
* @param refresh 如果为 true, 需重新生成缓存图片,比如:有短信发来的时候
*/
public void startVibrate(Mogoo_BitmapCache cache, int startFrameIndex, boolean refresh) {
startVibrate(cache, startFrameIndex, 0, refresh);
}
/**
* 停止图标抖动 @ author: 黄悦
*/
public void stopVibrate() {
if (!mVibration) {
return;
}
setDrawingCacheEnabled(false);
leftLimit = 0;
rightLimit = 0;
mVibration = false;
vibrationBitmaps = null;
postInvalidate();
}
public void stopVibrate(Mogoo_BitmapCache cache){
stopVibrate();
ShortcutInfo info = (ShortcutInfo) getTag();
cache.recycle(info.intent.getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_VIBRATION);
info = null;
}
/**
* 添加删除图标 @ author: 黄悦
*
* @param delIcon
*/
public void setDelIcon(Bitmap delIcon) {
this.delIcon = delIcon;
}
public Bitmap getDelIcon() {
return delIcon;
}
/**
* 添加计数图标 @ author: 黄悦
*
* @param countIcon
*/
public void setCountIcon(Mogoo_BitmapCache cache, int num, int type) {
Bitmap countIcon = cache.getDigitalIcon(num);
if (this.countIcon != null) {
Bitmap temp = this.countIcon;
temp = null;
}
this.countIcon = countIcon;
}
/**
* 绘制图标倒影 @ author:魏景春
*
* @param canvas 画布
*/
private void drawReflection(Canvas canvas) {
if (reflection && iconReflection != null) {
if (iconReflection.isRecycled()) {
iconReflection = ((ShortcutInfo) getTag())
.getIconReflection(((LauncherApplication) getContext()
.getApplicationContext()).getIconCache());
}
try{
canvas.drawBitmap(iconReflection, (float)(getScrollX() + getPaddingLeft() - 2), (float)(getScrollY() + getPaddingTop()
+ Mogoo_GlobalConfig.getIconHeight() + 2), null);
}catch (Exception e) {
System.out.println(e);
}
}
}
private void startVibrate(final Mogoo_BitmapCache cache, int startFrameIndex, final int times, final boolean refresh) {
if (!Mogoo_VibrationController.isVibrate || times > POST_START_TIME_LIMIT || mVibration) {
return;
}
int size = Mogoo_GlobalConfig.getFrameAngle().length;
if(startFrameIndex >= size){
startFrameIndex = size - 1;
}
if (!isDrawingCacheEnabled() && vibrationBitmaps == null) {
setDrawingCacheEnabled(true);
buildDrawingCache(true);
}
Bitmap bitmap = getDrawingCache();
if (bitmap == null || bitmap.isRecycled()) {
final int startIndex = startFrameIndex;
postDelayed(new Runnable() {
public void run() {
startVibrate(cache, startIndex, times, refresh);
}
}, 100);
return;
}
ShortcutInfo info = (ShortcutInfo) getTag();
Canvas canvas = new Canvas(bitmap);
// 删除图标描绘
drawDelIcon(canvas);
drawCountIcon(canvas);
canvas.save();
leftLimit = getScrollX() + getLeft();
rightLimit = getScrollY() + getRight();
mVibration = true;
if(refresh)
{
cache.recycle(info.intent.getComponent(), Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_VIBRATION);
}
vibrationBitmaps = info.getIconVibrate(cache, bitmap);
// frameIndex = startFrameIndex;
int len = vibrationBitmaps.length;
frameIndex = (int)(Math.random() * len);
setDrawingCacheEnabled(false);
buildDrawingCache(false);
bitmap = null;
info= null;
}
/*
* 绘制非系统软件删除标志 黄悦
*/
private void drawDelIcon(Canvas canvas) {
if (delIcon != null) {
canvas.drawBitmap(delIcon, 0, 0, paint);
}
}
/*
* 绘制抖动帧
*/
private void drawVibrateIcon(Canvas canvas) {
if (vibrationBitmaps == null || vibrationBitmaps[frameIndex].isRecycled()) {
super.draw(canvas);
if (vibrationBitmaps != null && vibrationBitmaps[frameIndex].isRecycled()) {
restartVibrate(
((LauncherApplication) getContext().getApplicationContext()).getIconCache(),
0);
}
return;
}
if (mVibration) {
drawRote(canvas);
}
}
/*
* 绘制旋转图
*/
private void drawRote(Canvas canvas) {
if (!mVibration) {
return;
}
// canvas.setDrawFilter(new PaintFlagsDrawFilter(0,
// Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));
canvas.drawBitmap(vibrationBitmaps[frameIndex], getScrollX(), getScrollY(), paint);
if (Math.abs(System.currentTimeMillis() - lastInvalTime) > 60) {
if (clockWiseRotate) {
if (++frameIndex >= frameCount) {
frameIndex = frameIndex - 2;
clockWiseRotate = false;
}
} else {
if (--frameIndex < 0) {
frameIndex = 1;
clockWiseRotate = true;
}
}
lastInvalTime = System.currentTimeMillis();
}
}
// /*
// * 绘制旋转图
// */
// private void drawRote(Canvas canvas) {
// if (!mVibration) {
// return;
// }
//
// if(this.nextFrame ==null)
// {
// nextFrame = Bitmap.createBitmap(vibrationBitmaps[frameIndex].getWidth(),
// vibrationBitmaps[frameIndex].getHeight(), Config.ARGB_8888);
// tempCanvas.setBitmap(nextFrame);
// tempCanvas.drawBitmap(vibrationBitmaps[frameIndex], 0,0, tempPaint);
// }
//
// canvas.drawBitmap(nextFrame, mScrollX, mScrollY, paint);
//
// if(clockwise)
// {
// if (++frameIndex >= frameCount) {
// --frameIndex;
// clockwise = false;
// }
// }else
// {
// if (--frameIndex < 0) {
// frameIndex = 0;
// clockwise = true;
// }
// }
//
//
// nextFrame = Bitmap.createBitmap(vibrationBitmaps[frameIndex].getWidth(),
// vibrationBitmaps[frameIndex].getHeight(), Config.ARGB_8888);
// tempCanvas.setBitmap(nextFrame);
// tempCanvas.drawBitmap(vibrationBitmaps[frameIndex], 0,0, tempPaint);
// }
/*
* 图标计数器初始化
*/
private void drawCountIcon(Canvas canvas) {
if (countIcon != null) {
Matrix matrx = new Matrix();
matrx.setTranslate(getScrollX() + getWidth() - countIcon.getWidth() - 2, getScrollY());
canvas.drawBitmap(countIcon, matrx, paint);
canvas.save();
}
}
/**
* 更新抖动帧 @ author: 黄悦
*
* @param cache
* @param startFrameIndex
*/
private void restartVibrate(Mogoo_BitmapCache cache, int startFrameIndex) {
stopVibrate();
cache.recycle(((ShortcutInfo) getTag()).intent.getComponent(),
Mogoo_BitmapCache.RECYCLE_COMPONENT_NAME_VIBRATION);
startVibrate(cache, startFrameIndex, 0, false);
}
/*
* 初始化
*/
private void init() {
frameCount = Mogoo_GlobalConfig.getFrameCount();
paint = new Paint();
paint.setTextSize(12);
paint.setAntiAlias(true);
// setOnTouchListener(this);
// add by 张永辉 2011-1-23
// 初始化padingTop,padingLeft,padingRight,paddingBottom
Mogoo_GlobalConfig.setConfigParm(Mogoo_GlobalConfig.WORKSPACE_CELL_PADDING_LEFT,
this.getPaddingLeft());
Mogoo_GlobalConfig.setConfigParm(Mogoo_GlobalConfig.WORKSPACE_CELL_PADDING_TOP,
this.getPaddingTop());
Mogoo_GlobalConfig.setConfigParm(Mogoo_GlobalConfig.WORKSPACE_CELL_PADDING_RIGHT,
this.getPaddingRight());
Mogoo_GlobalConfig.setConfigParm(Mogoo_GlobalConfig.WORKSPACE_CELL_PADDING_BOTTOM,
this.getPaddingBottom());
// end
}
/**
* 去掉桌面图标的右部渐入渐出效果
*
* @author 张永辉 2010-12-28
*/
@Override
protected float getRightFadingEdgeStrength() {
return 0;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)getLayoutParams();
// if(MT_GlobalConfig.LOG_DEBUG){
// Log.d(TAG, "topMargin="+lp.topMargin+" leftMargin="+lp.leftMargin+" rightMargin="+lp.rightMargin+" bottomMargin="+lp.bottomMargin) ;
// }
Mogoo_GlobalConfig.setConfigParm(Mogoo_GlobalConfig.WORKSPACE_CELL_MARGIN_TOP, lp.topMargin) ;
Mogoo_GlobalConfig.setConfigParm(Mogoo_GlobalConfig.WORKSPACE_CELL_MARGIN_LEFT, lp.leftMargin) ;
Mogoo_GlobalConfig.setConfigParm(Mogoo_GlobalConfig.WORKSPACE_CELL_MARGIN_RIGHT, lp.rightMargin) ;
Mogoo_GlobalConfig.setConfigParm(Mogoo_GlobalConfig.WORKSPACE_CELL_MARGIN_BOTTOM, lp.bottomMargin) ;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}