By 何明桂(http://blog.csdn.net/hmg25)轉載請註明出處
之前在網上看到有篇文章:Launcher之Dock細節篇http://news.wangmeng.cn/detailNews/2716-the-article-details-launcher-dock 它實現了一個仿Mac的dock。感覺蠻有意思的,所以就照著仿製了一個。
可以動態添加捷徑,預設包含AllApp按鈕,表徵圖置中顯示。
DockBar上的表徵圖可以相互交換位置,並且將表徵圖拖拽出去。
拖拽釋放後:
文章後邊附帶的源碼是基於android2.2內建的launcher2稍作修改而成,使用eclipse調試。
一、首先要在Launcher的setupViews函數裡面初始化自己的layout(需增加3個地方)
1. </p><p>dockbar=(DockBar)dragLayer.findViewById(R.id.dockbar);</p><p>dockbar.setLauncher(this); </p><p>dockbar.setDragController(dragController); </p><p>2.</p><p>dragController.setDragScoller(workspace);</p><p>dragController.setDragListener(deleteZone);</p><p>dragController.setDockDragListener(dockbar); // hmg25 add for dock</p><p>setDockDragListener為自訂函數,添加在DragController的startDrag中,具體見源碼</p><p>if(mDockListener!=null){ </p><p> mDockListener.onDragStart(source, dragInfo, dragAction); </p><p> }</p><p>3.</p><p>// The order here is bottom to top.</p><p>dragController.addDropTarget(workspace);</p><p>dragController.addDropTarget(dockbar); //hmg25 add for dock</p><p>dragController.addDropTarget(deleteZone);</p><p>
二、在layout-port的launcher.xml中增加
<!--hmg add for dock { --> </p><p> <com.android.launcher2.DockBar</p><p> android:id="@+id/dockbar"</p><p> android:layout_width="fill_parent"</p><p> android:layout_height="@dimen/button_bar_height"</p><p> android:layout_gravity="bottom|center_horizontal"</p><p> android:background="@drawable/dock_bg"</p><p> launcher:direction="horizontal"></p><p> <HorizontalScrollView android:id="@+id/dock_scroll_view" </p><p> android:scrollbars="none" </p><p> android:fadingEdge="none" </p><p> android:saveEnabled="false" </p><p> android:layout_width="fill_parent" </p><p> android:layout_height="fill_parent"></p><p> <LinearLayout android:orientation="horizontal" </p><p> android:id="@+id/dock_item_holder" </p><p> android:saveEnabled="false" </p><p> android:layout_width="fill_parent" </p><p> android:layout_height="fill_parent"></p><p> <com.android.launcher2.HandleView //預設將allapp按鈕添加進去</p><p> android:id="@+id/all_apps_button"</p><p> android:layout_centerHorizontal="true"</p><p> android:src="@drawable/all_apps_button"</p><p> launcher:direction="horizontal" </p><p> android:layout_width="fill_parent"</p><p> android:layout_height="fill_parent"</p><p> android:focusable="true"</p><p> android:clickable="true"</p><p> /></p><p> </LinearLayout></p><p> </HorizontalScrollView></p><p></com.android.launcher2.DockBar></p><p> <!--hmg add for dock } --><br />
三、建立自訂的類:
public class DockBar extends LinearLayout implements DropTarget, DragSource,</p><p>DragController.DragListener,View.OnLongClickListener {</p><p>@Override</p><p> public boolean acceptDrop(DragSource source, int x, int y, int xOffset,int yOffset,DragView dragView, Object dragInfo) { </p><p> //接受什麼類型的表徵圖 </p><p> Log.i("hmg", "DockBar->acceptDrop");</p><p> final ItemInfo item = (ItemInfo) dragInfo; </p><p> if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET </p><p> || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER </p><p> || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER </p><p> || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME </p><p> || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH </p><p> || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK) { </p><p> return false; </p><p> } </p><p> return true; </p><p> }</p><p>//拖拽釋放時響應下邊函數</p><p>@Override</p><p> public void onDrop(DragSource source, int x, int y, int xOffset,</p><p> int yOffset, DragView dragView, Object dragInfo) {</p><p> int position=0;</p><p> position=getLocation(x); //根據釋放時的座標,擷取插入位置</p><p> addItemAt((ItemInfo)dragInfo, position); </p><p> }</p><p>/*</p><p> * 傳入x座標,判斷新表徵圖的位置,此處僅判斷豎屏</p><p> */</p><p> public int getLocation(int x){ </p><p> for(int i=0;i<mItemHolder.getChildCount();i++){ </p><p> View iv = mItemHolder.getChildAt(i); </p><p> int[] position = new int[2];</p><p> //擷取座標,如果要適應橫屏可以稍作修改,比較Y值</p><p> iv.getLocationOnScreen(position);</p><p> //判斷釋放時新增的表徵圖在原表徵圖的之前還是之後</p><p> if(x<=(position[0]+(iv.getWidth()/2))){ </p><p> return i; </p><p> } </p><p> } </p><p> return mItemHolder.getChildCount(); </p><p> } </p><p>private void addItemAt(ItemInfo itemInfo, int position)</p><p> {</p><p> View view=null;</p><p> switch (itemInfo.itemType) {</p><p> case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:</p><p> case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: </p><p> ShortcutInfo shortcutInfo;</p><p> // 拖拽表徵圖來自於app list</p><p> if(itemInfo.container ==NO_ID&& itemInfo instanceof ApplicationInfo) </p><p> {</p><p> //與來自案頭的表徵圖包含資訊不一樣,具體看源碼</p><p> shortcutInfo= new ShortcutInfo((ApplicationInfo)itemInfo);</p><p> }</p><p> else</p><p> shortcutInfo = (ShortcutInfo)itemInfo; //拖拽表徵圖來自案頭</p><p> //調用Launcher中的CreateDockShortcut產生一個imageView</p><p> view = mLauncher. CreateDockShortcut (shortcutInfo);</p><p> view.setOnLongClickListener(this); </p><p> break;</p><p> case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:</p><p> break;</p><p> default:</p><p> throw new IllegalStateException("Unknown item type: "</p><p> + itemInfo.itemType);</p><p> } </p><p> mItemHolder.addView(view, position); </p><p>}</p><p>之所以將建立view用Launcher. CreateDockShortcut是想直接使用Launcher中的單擊事件。</p><p>View CreateDockShortcut (ShortcutInfo shortcutInfo)</p><p> { </p><p> Context context=getApplicationContext();</p><p> ImageView imageView =new ImageView(context); </p><p> imageView.setImageBitmap(shortcutInfo.mIcon);</p><p> imageView.setOnClickListener(this);</p><p> imageView.setFocusable(true);</p><p> imageView.setTag(shortcutInfo);</p><p> imageView.setMinimumWidth(100);</p><p> return imageView;</p><p> }</p><p> 在dock上長按,拖拽交換位置或者拖拽出去</p><p>@Override</p><p> public boolean onLongClick(View v) {</p><p> // TODO Auto-generated method stub</p><p> if (mLauncher.isAllAppsVisible())</p><p> mLauncher.closeAllApps(false);</p><p> mSelectedView = v; </p><p>//開始拖拽</p><p> mDragController.startDrag(v, this, v.getTag(),</p><p> DragController.DRAG_ACTION_MOVE);</p><p> removeSelectedItem();</p><p> return true;</p><p> }</p><p>private void removeSelectedItem()</p><p> {</p><p> if (mSelectedView == null)</p><p> return;</p><p> mItemHolder.removeView(mSelectedView);</p><p> }</p><p>
代碼修改了不少地方,具體看代碼,修改的地方我都標註啦 ~~歡迎大家指教,相互交流~~
源碼地址:http://download.csdn.net/source/3142047