android Launcher源碼解析03:仿Mac的Dock

來源:互聯網
上載者:User

       之前在網上看到有篇文章:Launcher之Dock細節篇http://www.linuxidc.com/Linux/2011-09/44160.htm 它實現了一個仿Mac的dock。感覺蠻有意思的,所以就照著仿製了一個。

        可以動態添加捷徑,預設包含AllApp按鈕,表徵圖置中顯示。

DockBar上的表徵圖可以相互交換位置,並且將表徵圖拖拽出去。

拖拽釋放後:

文章後邊附帶的源碼是基於Android2.2內建的launcher2稍作修改而成,使用eclipse調試。
一、首先要在Launcher的setupViews函數裡面初始化自己的layout(需增加3個地方)

1、

 // hmg add for dock {    dockbar = (DockBar) dragLayer.findViewById(R.id.dockbar);    dockbar.setLauncher(this);    dockbar.setDragController(dragController);    // hmg add for dock }

2、

 dragController.setDragScoller(workspace);        dragController.setDragListener(deleteZone);        dragController.setDockDragListener(dockbar); // hmg25 add for dock        dragController.setScrollView(dragLayer);        dragController.setMoveTarget(workspace);

setDockDragListener為自訂函數,添加在DragController的startDrag中,具體見源碼 

//hmg25 add for dock {         if(mDockListener!=null){               mDockListener.onDragStart(source, dragInfo, dragAction);         }        //hmg25 add for dock } 

3、

// The order here is bottom to top.        dragController.addDropTarget(workspace);        dragController.addDropTarget(dockbar); // hmg25 add for dock        dragController.addDropTarget(deleteZone);

二、在layout-port的launcher.xml中增加

 <!-- hmg25 add for dock {  -->  <com.xuxm.demo.launcher.DockBar        android:id="@+id/dockbar"        android:layout_width="fill_parent"        android:layout_height="@dimen/button_bar_height"        android:layout_gravity="bottom|center_horizontal"        android:background="@drawable/dock_bg"        launcher:direction="horizontal">        <HorizontalScrollView android:id="@+id/dock_scroll_view"         android:scrollbars="none"         android:fadingEdge="none"         android:saveEnabled="false"         android:layout_width="fill_parent"         android:layout_height="fill_parent">        <LinearLayout android:orientation="horizontal"         android:id="@+id/dock_item_holder"              android:saveEnabled="false"         android:layout_width="fill_parent"         android:layout_height="fill_parent">         <com.xuxm.demo.launcher.HandleView            android:id="@+id/all_apps_button"            android:layout_centerHorizontal="true"            android:src="@drawable/hotseat_all_apps"               launcher:direction="horizontal"                    android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:focusable="true"            android:clickable="true"            />        </LinearLayout>    </HorizontalScrollView></com.xuxm.demo.launcher.DockBar> <!-- hmg25 add for dock  } --> 

三、建立自訂的類:

package com.xuxm.demo.launcher;import android.content.Context;import android.graphics.Rect;import android.util.AttributeSet;import android.util.Log;import android.view.Gravity;import android.view.View;import android.widget.FrameLayout;import android.widget.LinearLayout;public class DockBar  extends LinearLayout implements DropTarget, DragSource,DragController.DragListener,View.OnLongClickListener{private Launcher mLauncher;    private DragController mDragController;    private Workspace mWorkspace;    private View mDragView;    private LinearLayout mItemHolder;    private View mScrollView;    private View mSelectedView;public DockBar(Context context){       super(context);   // TODO Auto-generated constructor stub}     public DockBar(Context context, AttributeSet attrs) {          super(context, attrs);                }        @Override    protected void onFinishInflate() {        // TODO Auto-generated method stub    Log.i("hmg", "DockBar->onFinishInflate");    mItemHolder  = (LinearLayout)findViewById(R.id.dock_item_holder);    mScrollView= findViewById(R.id.dock_scroll_view);         super.onFinishInflate();    }        @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        // TODO Auto-generated method stub        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        //置中顯示        FrameLayout.LayoutParams lp= (FrameLayout.LayoutParams)mItemHolder.getLayoutParams();        lp.gravity=Gravity.CENTER;        mItemHolder.setLayoutParams(lp);        postInvalidate();        requestLayout();    }    @Override    public boolean onLongClick(View v) {// TODO Auto-generated method stub    if (mLauncher.isAllAppsVisible())    mLauncher.closeAllApps(false);    mSelectedView = v;       mDragController.startDrag(v, this, v.getTag(),    DragController.DRAG_ACTION_MOVE);    removeSelectedItem();    return true;    }    private void removeSelectedItem()    {    if (mSelectedView == null)    return;        mItemHolder.removeView(mSelectedView);    }@Overridepublic void onDragStart(DragSource source, Object info, int dragAction) {// TODO Auto-generated method stubLog.i("hmg", "DockBar->onDragStart");}@Overridepublic void onDragEnd() {// TODO Auto-generated method stub}@Overridepublic void setDragController(DragController dragger) {// TODO Auto-generated method stubmDragController = dragger;}void setLauncher(Launcher launcher) {mLauncher = launcher;}void setWorkspace(Workspace workspace ){mWorkspace=workspace;}@Overridepublic void onDropCompleted(View target, boolean success) {// TODO Auto-generated method stub}/*     * 拖拽釋放時響應     */    @Override    public void onDrop(DragSource source, int x, int y, int xOffset,    int yOffset, DragView dragView, Object dragInfo) {    int position=0;    position=getLocation(x); //根據釋放時的座標,擷取插入位置    addItemAt((ItemInfo)dragInfo, position);     }@Overridepublic void onDragEnter(DragSource source, int x, int y, int xOffset,int yOffset, DragView dragView, Object dragInfo) {// TODO Auto-generated method stubLog.i("hmg", "DockBar->onDragEnter");setBackgroundResource(R.drawable.dock_bg_press); }@Overridepublic void onDragOver(DragSource source, int x, int y, int xOffset,int yOffset, DragView dragView, Object dragInfo) {// TODO Auto-generated method stub}private void addItemAt(ItemInfo itemInfo, int position)    {View view=null;switch (itemInfo.itemType) {case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:ShortcutInfo shortcutInfo;// 拖拽表徵圖來自於app listif(itemInfo.container ==NO_ID&& itemInfo instanceof ApplicationInfo)    {//與來自案頭的表徵圖包含資訊不一樣,具體看源碼shortcutInfo= new ShortcutInfo((ApplicationInfo)itemInfo);}elseshortcutInfo = (ShortcutInfo)itemInfo; //拖拽表徵圖來自案頭//調用Launcher中的createSmallShortcut產生一個imageViewview = mLauncher.CreateDockShortcut(shortcutInfo);view.setOnLongClickListener(this);break;case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:break;default:throw new IllegalStateException("Unknown item type: "+ itemInfo.itemType);} mItemHolder.addView(view, position);      }/*     * 傳入x座標,判斷新表徵圖的位置,此處僅判斷豎屏     */    public int getLocation(int x){          for(int i=0;i<mItemHolder.getChildCount();i++){              View iv = mItemHolder.getChildAt(i);                   int[] position = new int[2];           //擷取座標,如果要適應橫屏可以稍作修改,比較Y值           iv.getLocationOnScreen(position);           //判斷釋放時新增的表徵圖在原表徵圖的之前還是之後            if(x<=(position[0]+(iv.getWidth()/2))){                                       return i;                              }                          }            return mItemHolder.getChildCount();       }  @Overridepublic void onDragExit(DragSource source, int x, int y, int xOffset,int yOffset, DragView dragView, Object dragInfo) {// TODO Auto-generated method stubsetBackgroundResource(R.drawable.dock_bg); mItemHolder.removeView(mDragView);Log.i("hmg", "DockBar->onDragExit");}@Overridepublic boolean acceptDrop(DragSource source, int x, int y, int xOffset,int yOffset, DragView dragView, Object dragInfo) {// TODO Auto-generated method stub//接受什麼類型的表徵圖        Log.i("hmg", "DockBar->acceptDrop");final ItemInfo item = (ItemInfo) dragInfo;       if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET                || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER                || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER                 || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME                || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH                || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK) {         return false;        }  return true; }@Overridepublic Rect estimateDropLocation(DragSource source, int x, int y,int xOffset, int yOffset, DragView dragView, Object dragInfo,Rect recycle) {// TODO Auto-generated method stubreturn null;}       }

參考資料:

《Android開發:為launcher添加一個仿Mac的Dock(附源碼)》

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.