主要要的逻辑就是想办法替换掉应用icon的drawable,然后通过自定义drawable的方式来实现动态Icon。
直接贴代码吧,没什么难的。
首先在IconCache.java 中的修改
private static class CacheEntry {
public Bitmap icon;
public CharSequence title;
public CharSequence contentDescription;
public IconScript script;//icon的脚本
}
public IconScript getScript(Intent intent, UserHandleCompat user){
synchronized (mCache) {
ComponentName component = intent.getComponent();
if (component == null) {
return null;
}
LauncherActivityInfoCompat launcherActInfo = mLauncherApps.resolveActivity(intent, user);
CacheEntry entry = cacheLocked(component, launcherActInfo, null, user, true, -1);
return entry.script;
}
}
private CacheEntry cacheLocked(ComponentName componentName, LauncherActivityInfoCompat info,
HashMap
ShortcutInfo.java
public IconScript getScript(IconCache iconCache){
return iconCache.getScript(promisedIntent != null ? promisedIntent : intent, user);
}
public void applyFromShortcutInfo(ShortcutInfo info, IconCache iconCache,
boolean setDefaultPadding, boolean promiseStateChanged) {
……
mScript = info.getScript(iconCache);
……
}
@Override
public void setCompoundDrawables(Drawable left, Drawable top,
Drawable right, Drawable bottom) {
if(top != null){
if(mScript != null){
top = mScript;
mScript.setBounds(top.getBounds());
if(!mScript.isRuning)
mScript.run(this);
}
}
super.setCompoundDrawables(left, top, right, bottom);
}
public class IconScript extends Drawable{
public boolean isRuning = false;
public FastBitmapDrawable mFastBitmapDrawable = null;
protected Paint mPaint = new Paint();
public IconScript(){
mPaint.setAntiAlias(true);
mPaint.setFilterBitmap(true);
}
public void draw(Canvas canvas){
if(mFastBitmapDrawable != null){
canvas.drawBitmap(mFastBitmapDrawable.getBitmap(), null, getBounds(),mPaint);//画底图
}
}
/**
* 运行脚本
* @param view
*/
public void run(View view){
isRuning = true;
}
/**
* 停止脚本
* (未调用,暂留入口)
*/
public void onStop(){
isRuning = false;
}
/**
* 暂停脚本
* (未调用,暂留入口)
*/
public void onPause(){
isRuning = false;
}
/**
* 恢复脚本
* (未调用,暂留入口)
*/
public void onResume(){
isRuning = true;
}
@Override
public int getOpacity() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void setAlpha(int arg0) {
// TODO Auto-generated method stub
}
@Override
public void setColorFilter(ColorFilter arg0) {
// TODO Auto-generated method stub
}
@Override
public int getIntrinsicWidth() {
int width = getBounds().width();
if (width == 0) {
width = mFastBitmapDrawable.getBitmap().getWidth();
}
return width;
}
@Override
public int getIntrinsicHeight() {
int height = getBounds().height();
if (height == 0) {
height = mFastBitmapDrawable.getBitmap().getHeight();
}
return height;
}
@Override
public int getMinimumWidth() {
return getBounds().width();
}
@Override
public int getMinimumHeight() {
return getBounds().height();
}
@Override
public void setFilterBitmap(boolean filterBitmap) {
mPaint.setFilterBitmap(filterBitmap);
mPaint.setAntiAlias(filterBitmap);
}
public void setFastBitmapDrawable(FastBitmapDrawable drawable){
mFastBitmapDrawable = drawable;
}
public FastBitmapDrawable setFastBitmapDrawable(){
return mFastBitmapDrawable;
}
}
* 实现桌面时钟Icon动态显示。
* 2015.4.1
* @author gholl
*
*/
public class ClockScript extends IconScript {
Rect mRect = null;
/**
* 效果展示目标View
*/
private View mView;
/**
* 通知系统更新视图现成
*/
private ClockThread mClockThread = null;
/**
* 当前是否显示在屏幕上
*/
private boolean mIsShowInScreen = false;
public ClockScript(){
super();
}
public void run(View view) {
mView = view;
mRect = getBounds();
if(mClockThread == null){
mClockThread = new ClockThread();
mClockThread.start();
}
}
@Override
public void onPause() {
mClockThread.pauseRun();
super.onPause();
}
@Override
public void onResume() {
mClockThread.resumeRun();
super.onResume();
}
@Override
public void onStop() {
mClockThread.stopRun();
super.onStop();
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
mIsShowInScreen = true;
// mPaint.setColor(Color.WHITE);
// canvas.drawCircle(mRect.centerX(), mRect.centerY(), mRect.height()/2, mPaint);
// mPaint.setColor(Color.BLACK);
// canvas.drawLine(mRect.centerX(), 0, mRect.centerX(), 10, mPaint);
// canvas.drawLine(mRect.centerX(), mRect.height(), mRect.centerX(), mRect.height()-10, mPaint);
// canvas.drawLine(mRect.left, mRect.centerY(), mRect.left + 10, mRect.centerY(), mPaint);
// canvas.drawLine(mRect.right, mRect.centerY(), mRect.right-10, mRect.centerY(), mPaint);
drawIndicator(canvas,mRect.centerX(),mRect.centerY(),mPaint);
// mPaint.setColor(Color.MAGENTA);
canvas.drawCircle(mRect.centerX(), mRect.centerY(), 3, mPaint);
if(mClockThread.wait){
mClockThread.resumeRun();
}
}
/**
* 画指针
* @param canvas
* @param centerX
* @param centerY
* @param p
*/
private void drawIndicator(Canvas canvas,int centerX,int centerY,Paint p){
Time t=new Time();
t.setToNow();
p.setStrokeWidth(2);
p.setColor(Color.BLACK);
//时针
canvas.drawLine(centerX, centerY,
(int)(centerX + (mRect.width()/2-35) * Math.cos((t.hour+(float)t.minute/60) * (Math.PI / 6) - Math.PI / 2)),
(int)(centerY + (mRect.width()/2-35) * Math.sin((t.hour+(float)t.minute/60) * (Math.PI / 6) - Math.PI / 2)), p);
canvas.drawLine(centerX, centerY,
(int)(centerX + (mRect.width()/2-50) * Math.cos((t.hour+(float)t.minute/60) * (Math.PI / 6) + Math.PI / 2)),
(int)(centerY + (mRect.width()/2-50) * Math.sin((t.hour+(float)t.minute/60) * (Math.PI / 6) + Math.PI / 2)), p);
// p.setColor(Color.GREEN);
//分针
canvas.drawLine(centerX, centerY,
(int)(centerX + (mRect.width()/2-27) * Math.cos(t.minute * (Math.PI / 30) - Math.PI / 2)),
(int)(centerY + (mRect.width()/2-27) * Math.sin(t.minute * (Math.PI / 30) - Math.PI / 2)),p);
canvas.drawLine(centerX, centerY,
(int)(centerX + (mRect.width()/2-48) * Math.cos(t.minute * (Math.PI / 30) + Math.PI / 2)),
(int)(centerY + (mRect.width()/2-48) * Math.sin(t.minute * (Math.PI / 30) + Math.PI / 2)),p);
p.setColor(Color.RED);
//秒针
canvas.drawLine(centerX, centerY,
(int)(centerX + (mRect.width()/2-24) * Math.cos(t.second * (Math.PI / 30) - Math.PI / 2)),
(int)(centerY + (mRect.width()/2-24) * Math.sin(t.second * (Math.PI / 30) - Math.PI / 2)),p);
p.setStrokeWidth(3);
canvas.drawLine(centerX, centerY,
(int)(centerX + (mRect.width()/2-45) * Math.cos(t.second * (Math.PI / 30) + Math.PI/2)),
(int)(centerY + (mRect.width()/2-45) * Math.sin(t.second * (Math.PI / 30) + Math.PI/2)),p);
}
class ClockThread extends Thread {
int times = 0;
boolean running = true;
public boolean wait = false;
public void stopRun() {
running = false;
synchronized (this) {
this.notify();
}
};
public void pauseRun() {
this.wait = true;
synchronized (this) {
this.notify();
}
}
public void resumeRun() {
this.wait = false;
synchronized (this) {
this.notify();
}
}
public void run() {
while (running) {
synchronized (mView) {
mView.postInvalidate();
}
if(!mIsShowInScreen){
pauseRun();
}
mIsShowInScreen = false;
try {
Thread.sleep(500);
} catch (Exception e) {
System.out.println(e);
}
synchronized (this) {
if (wait) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
}
/**
* 实现桌面日历Icon动态显示。
* @author gholl
*
*/
public class CalendarScript extends IconScript {
private float mDensity = 1.5f;
Time mTime = new Time();
Context mContext;
public CalendarScript() {
super();
mContext = LauncherApplication.CONTEXT;
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
mTime.setToNow();
canvas.drawBitmap(getRes(mTime.monthDay), null, getBounds(), mPaint);
}
@Override
public void run(final View view) {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_DATE_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
view.getContext().registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
view.postInvalidate();
}
}, filter);
super.run(view);
}
private Bitmap getRes(int monthDay){
int res = mContext.getResources().getIdentifier("ic_launcher_calendar_" + monthDay, "drawable", mContext.getPackageName());
BitmapDrawable bitmapDrawable = (BitmapDrawable)mContext.getResources().getDrawable(res);
return bitmapDrawable.getBitmap();
}
}