转载自:http://blog.csdn.net/pinsengjixuhezhou/article/details/45890569
注:这篇文章 主要内容和思路还是转自上面链接中博主的文章,我在实际使用过程中根据自己的需求有些调整。
主要要的逻辑就是想办法替换掉应用icon的drawable,然后通过自定义drawable的方式来实现动态Icon。
直接贴代码吧,没什么难的。
首先在IconCache.java 中的修改
ShortcutInfo.java
@Override public void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) { // TODO Auto-generated method stub if(top != null){ if(mScript != null){ top = mScript; Rect rect = new Rect(); rect.set(0, 0, LauncherAppState.getInstance().getInvariantDeviceProfile().iconBitmapSize, LauncherAppState.getInstance().getInvariantDeviceProfile().iconBitmapSize); mScript.setBounds(rect); if(!mScript.isRuning){ mScript.run(this); } } } super.setCompoundDrawables(left, top, right, bottom); }
</pre><pre code_snippet_id="1674198" snippet_file_name="blog_20160506_3_9573334" name="code" class="java">/** * dynamic calendar Icon * */ public class CalendarScript extends IconScript { Time mTime = new Time(); Rect mSrcRect = new Rect(); Rect mDestRect = new Rect(); Context mContext; public CalendarScript() { super(); mContext = LauncherAppState.getInstance().getContext(); } @Override public void draw(Canvas canvas) { super.draw(canvas); mTime.setToNow(); // canvas.drawBitmap(getRes(mTime.monthDay), null, getBounds(), mPaint); Bitmap calendarBackground = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.calendar); Bitmap dayOfMonthRes = getCalendarDataRes(mTime.monthDay); Bitmap dayOfWeekRes = getCalendarWeekDayRes(mTime.weekDay); int width = LauncherAppState.getInstance().getInvariantDeviceProfile().iconBitmapSize; int height = width; mDestRect.set(0, 0, width, height); mSrcRect.set(0, 0, calendarBackground.getWidth(), calendarBackground.getHeight()); canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG)); canvas.drawBitmap(calendarBackground, mSrcRect, mDestRect, null); canvas.drawBitmap(dayOfMonthRes, (width - dayOfMonthRes.getWidth()) / 2 , (height - dayOfMonthRes.getHeight()) / 2 + 10, null); canvas.drawBitmap(dayOfWeekRes, (width - dayOfWeekRes.getWidth()) / 2, dayOfWeekRes.getHeight(), null); canvas.save(Canvas.ALL_SAVE_FLAG); canvas.restore(); } @Override public void run(final View view) { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_DATE_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); filter.addAction("android.intent.action.TIME_SET"); view.getContext().registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context arg0, Intent arg1) { view.postInvalidate(); } }, filter); super.run(view); } private Bitmap getCalendarDataRes(int monthDay){ int res = mContext.getResources().getIdentifier("calendar_data_" + monthDay, "drawable", mContext.getPackageName()); BitmapDrawable bitmapDrawable = (BitmapDrawable)mContext.getResources().getDrawable(res); return bitmapDrawable.getBitmap(); } private Bitmap getCalendarWeekDayRes(int weekDay){ int res = mContext.getResources().getIdentifier("calendar_week_" + weekDay, "drawable", mContext.getPackageName()); BitmapDrawable bitmapDrawable = (BitmapDrawable)mContext.getResources().getDrawable(res); return bitmapDrawable.getBitmap(); } }
/** * dynamic Clock Icon * */ public class ClockScript extends IconScript { Rect mSrcRect = new Rect(); Rect mDestRect = new Rect(); private int mIconSize; private Context mContext; private Time mTime; private Bitmap mSecond, mMinute, mHour, mBackground; private int mHiegtOffset, mWidthOffset; /** * Results show target View */ private View mView; /** * notify System to invalidate */ private ClockThread mClockThread = null; /** * is showen on the screen now */ private boolean mIsShowInScreen = false; public ClockScript(){ super(); mContext = LauncherAppState.getInstance().getContext(); mIconSize = LauncherAppState.getInstance().getInvariantDeviceProfile().iconBitmapSize; } public void run(View view) { mView = view; mTime = new Time(); mBackground = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.launcher_theme_ic_app_clock_bg);//getBounds(); mSecond = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.launcher_theme_ic_app_clock_second_draw_by_pic); mMinute = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.launcher_theme_ic_app_clock_minute_draw_by_pic); mHour = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.launcher_theme_ic_app_clock_hour_draw_by_pic); mDestRect.set(0, 0, mIconSize, mIconSize); mSrcRect.set(0, 0, mBackground.getWidth(), mBackground.getHeight()); mHiegtOffset = (mIconSize - mBackground.getHeight()) / 2; mWidthOffset = (mIconSize - mSecond.getWidth()) / 2; 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); // mPaint.setColor(Color.MAGENTA); // canvas.drawCircle(mRect.centerX(), mRect.centerY(), 3, mPaint); if(mClockThread.wait){ mClockThread.resumeRun(); } } /** * draw Indicator * @param canvas * @param centerX * @param centerY * @param p */ private void drawIndicator(Canvas canvas){ mTime.setToNow(); // p.setStrokeWidth(2); // p.setColor(Color.BLACK); float hourAngle = (float)mTime.hour / 12 * 360 + (float)mTime.minute / 60 * (360 / 12); float minAngle = (float)mTime.minute / 60 * 360; float secAngle = (float)mTime.second / 60 * 360; canvas.save(); canvas.drawBitmap(mBackground, mSrcRect, mDestRect, null); canvas.restore(); canvas.save(); canvas.rotate(hourAngle, mIconSize / 2, mIconSize / 2); canvas.drawBitmap(mHour, mWidthOffset, mHiegtOffset, null); canvas.restore(); canvas.save(); canvas.rotate(minAngle, mIconSize / 2, mIconSize / 2); canvas.drawBitmap(mMinute, mWidthOffset, mHiegtOffset, null); canvas.restore(); canvas.save(); canvas.rotate(secAngle, mIconSize / 2, mIconSize / 2); canvas.drawBitmap(mSecond, mWidthOffset, mHiegtOffset, null); canvas.restore(); // canvas.drawLine(centerX, centerY, // (int)(centerX + (mRect.width()/2-35) * Math.cos((mTime.hour+(float)mTime.minute/60) * (Math.PI / 6) - Math.PI / 2)), // (int)(centerY + (mRect.width()/2-35) * Math.sin((mTime.hour+(float)mTime.minute/60) * (Math.PI / 6) - Math.PI / 2)), p); // canvas.drawLine(centerX, centerY, // (int)(centerX + (mRect.width()/2-50) * Math.cos((mTime.hour+(float)mTime.minute/60) * (Math.PI / 6) + Math.PI / 2)), // (int)(centerY + (mRect.width()/2-50) * Math.sin((mTime.hour+(float)mTime.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(mTime.minute * (Math.PI / 30) - Math.PI / 2)), // (int)(centerY + (mRect.width()/2-27) * Math.sin(mTime.minute * (Math.PI / 30) - Math.PI / 2)),p); // canvas.drawLine(centerX, centerY, // (int)(centerX + (mRect.width()/2-48) * Math.cos(mTime.minute * (Math.PI / 30) + Math.PI / 2)), // (int)(centerY + (mRect.width()/2-48) * Math.sin(mTime.minute * (Math.PI / 30) + Math.PI / 2)),p); //// p.setColor(Color.RED); // //秒针 // canvas.drawLine(centerX, centerY, // (int)(centerX + (mRect.width()/2-24) * Math.cos(mTime.second * (Math.PI / 30) - Math.PI / 2)), // (int)(centerY + (mRect.width()/2-24) * Math.sin(mTime.second * (Math.PI / 30) - Math.PI / 2)),p); //// p.setStrokeWidth(3); // canvas.drawLine(centerX, centerY, // (int)(centerX + (mRect.width()/2-45) * Math.cos(mTime.second * (Math.PI / 30) + Math.PI/2)), // (int)(centerY + (mRect.width()/2-45) * Math.sin(mTime.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(); } } } } } } }