主要要的逻辑就是想办法替换掉应用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 labelCache, UserHandleCompat user,            boolean usePackageIcon, int unreadNum) {……     if(componentName.getPackageName().equals("com.android.deskclock"))            entry.script = new ClockScript();            if(componentName.getPackageName().equals("com.android.calendar"))            entry.script = new CalendarScript();            return entry;}


ShortcutInfo.java

    public IconScript getScript(IconCache iconCache){    return iconCache.getScript(promisedIntent != null ? promisedIntent : intent, user);    }

BubbleTextView.java

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;}@Overridepublic int getOpacity() {// TODO Auto-generated method stubreturn 0;}@Overridepublic void setAlpha(int arg0) {// TODO Auto-generated method stub}@Overridepublic 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();}}@Overridepublic void onPause() {mClockThread.pauseRun();super.onPause();}@Overridepublic void onResume() {mClockThread.resumeRun();super.onResume();}@Overridepublic void onStop() {mClockThread.stopRun();super.onStop();}@Overridepublic 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 blocke.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;}@Overridepublic void draw(Canvas canvas) {super.draw(canvas);mTime.setToNow();canvas.drawBitmap(getRes(mTime.monthDay), null, getBounds(), mPaint);}@Overridepublic 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() {@Overridepublic 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();}}





更多相关文章

  1. Android(安卓)Studio Error -- Could not create the Java Virtu
  2. Android中使用gridview如何让图片在上文字在下
  3. 使用Jenkins自动构建Android问题总结
  4. Android(安卓)OTA 升级
  5. 在android 4.2.2上调试MU609步骤,WCDMA
  6. 在android中执行bash 循环
  7. 《Android(安卓)uiautomatorviewer不能截图》
  8. Android(安卓)Studio + smalidea进行smail动态调试
  9. Android(安卓)系统设置默认launcher

随机推荐

  1. 一步步教你用实现HTML5 SVG动画效果 [每
  2. 轻松解决Github连接缓慢、图裂问题
  3. Conda太慢?试试这个加速工具!
  4. 25页PPT | 如何利用python进行地图可视化
  5. 解决matplotlib文字标签遮挡问题
  6. 基于geopandas的空间数据分析—geoplot篇
  7. geopandas&geoplot近期重要更新
  8. 20 行代码:Serverless 架构下用 Python 轻
  9. 成天说要删库跑路,这次真的有人干了
  10. Python+Kepler.gl轻松制作时间轮播地图