使用用ADW的Launcher的人應該有點印象裡面的功能,就是拖拽應用或者Widget表徵圖到刪除表徵圖上,停留1秒以上,
則會顯示"Drop to uninstall"的提示,放開則開啟卸載該程式的介面,現在就是要分析模仿這個功能。
主要用到有兩方面的東西,卸載和停留提示。
卸載主要使用的是:
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE,<br /> Uri.parse("package:" + mUninstallPkg));<br /> DeleteZone.this.getContext().startActivity(uninstallIntent);
從這個來看,要卸載一個應用,主要是知道其PackageName即可。
當拖拽表徵圖到刪除欄上,停留超過一定時間的時候,就轉到卸載的模式,這個可以用Handler的
postDelayed (Runnable r, long delayMillis)
來實現。
我們現在來分析一下拖拽所產生的響應事件,
當開始拖拽的時候,首先啟動並執行是:
onDragStart->onDragOver->onDragExit->onDragEnd.
當把表徵圖拖動進入刪除地區的時候,會執行onDragEnter,移出則執行onDragExit.
而如果表徵圖是拖入到刪除地區再鬆開的話,則會是onDragEnter->onDragDrop->onDragExit->onDragEnd.
拖動結束一定會執行的兩個事件是onDragExit->onDragEnd.其中onDragExit在onDragEnd之前發生。
因此在onDragEnter的時候,讀取PackageName和postDelayed發送一個延遲訊息給Runnable(設定卸載標誌)
然後在onDragExit裡面再
removeCallbacks (Runnable r)移除隊列裡面的訊息,
並postDelayed一個訊息,清空卸載標誌,當然這裡的延遲時間要比前面onDragEnter裡面的時間要小得多,
這樣實現的效果是:
1. 如果是拖拽進刪除地區,再拖出來的時候,會清空卸載標誌;
2. 如果是拖拽進刪除地區足夠長時間再放開(應該開啟卸載介面,已經設定卸載標誌),確保延遲的時間內onDragEnd已經執行,因為postDelayed是清空卸載標誌的,所以如果要保留卸載標誌,需要延遲時間要比onDragEnd執行時間大。
最後在onDragEnd的時候,判斷卸載標誌和程式PackageName如果符合條件則執行卸載動作。
呵呵,說得不是很清楚,下面上主要源碼:
// Yao.GUET add 2011-04-08<br /> private static final String TAG="DeleteZone";<br /> private static final int STAY_OVER_TIME = 1500;<br /> private static boolean mUninstall;<br /> private boolean mEnterDelZone;<br /> private String mUninstallPkg;<br /> private final Handler mHandler = new Handler();<br /> private final Runnable mShowUnstaller = new Runnable() {<br />public void run() {<br />// TODO Auto-generated method stub<br />Log.e(TAG, "Runnable ShowUnstaller is called!");<br />mUninstall = mEnterDelZone;<br />if (mUninstall == true) {<br />Toast.makeText(mContext, "Drop to unstall the app!", 500).show();<br />}<br />}</p><p> };
onDragEnter:
// Yao.GUET<br /> Log.e(TAG, "DragEnter");<br /> if (item instanceof LauncherAppWidgetInfo ||<br /> item instanceof ApplicationInfo ||<br /> item instanceof ShortcutInfo) {<br /> mHandler.removeCallbacks(mShowUnstaller);<br /> Log.e(TAG, "postDelayed");<br /> mEnterDelZone = true;<br /> mHandler.postDelayed(mShowUnstaller, STAY_OVER_TIME);</p><p> // get the package name<br /> if (item instanceof ApplicationInfo) {<br /> final ApplicationInfo ai = (ApplicationInfo)item;<br /> mUninstallPkg = ai.componentName.getPackageName();<br /> if (this.getClass().getPackage().getName().equals(mUninstallPkg))<br /> mUninstallPkg = null;<br /> } else if (item instanceof LauncherAppWidgetInfo) {<br /> final LauncherAppWidgetInfo appwidget = (LauncherAppWidgetInfo)item;<br /> final AppWidgetProviderInfo ap = AppWidgetManager.getInstance(mLauncher)<br /> .getAppWidgetInfo(appwidget.appWidgetId);<br /> if (ap != null)<br /> mUninstallPkg = ap.provider.getPackageName();<br /> } else if (item instanceof ShortcutInfo) {<br /> final ShortcutInfo scInfo = (ShortcutInfo)item;<br /> if (scInfo.iconResource != null) {<br /> mUninstallPkg = scInfo.iconResource.packageName;<br /> } else if (scInfo.intent != null) {<br /> mUninstallPkg = scInfo.intent.getComponent().getPackageName();<br /> }<br /> }
onDragExit:
// Yao.GUET add to remove the call back function<br /> Log.e(TAG, "DragExit");<br /> mHandler.removeCallbacks(mShowUnstaller);<br /> dragView.setPaint(null);<br /> if (mUninstall == true) {<br /> mEnterDelZone = false;<br /> mHandler.postDelayed(mShowUnstaller, 100);<br /> }
onDragEnd:
// Yao.GUET deal the uninstall flag when drag is end<br /> Log.e(TAG, "flag:" + mUninstall + ", pkg:" + mUninstallPkg);<br /> if (mUninstall && (mUninstallPkg != null)) {<br /> Intent uninstallIntent = new Intent(Intent.ACTION_DELETE,<br /> Uri.parse("package:" + mUninstallPkg));<br /> DeleteZone.this.getContext().startActivity(uninstallIntent);<br /> }
運行: