Android(安卓)Launcher 动态icon【时钟】【日历】
16lz
2021-01-25
主要要的逻辑就是想办法替换掉应用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); }
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();}}
更多相关文章
- Android(安卓)Studio Error -- Could not create the Java Virtu
- Android中使用gridview如何让图片在上文字在下
- 使用Jenkins自动构建Android问题总结
- Android(安卓)OTA 升级
- 在android 4.2.2上调试MU609步骤,WCDMA
- 在android中执行bash 循环
- 《Android(安卓)uiautomatorviewer不能截图》
- Android(安卓)Studio + smalidea进行smail动态调试
- Android(安卓)系统设置默认launcher