android自訂viewgroup初步之一----抽屜菜單

來源:互聯網
上載者:User

標籤:android   animation   自訂   viewgroup   

幾天前在慕課網上看到鴻洋老師的 自訂衛星菜單,感覺很有意思,於是看完視頻以後,自己也嘗試寫了一遍,並且添加了可拖拽效果(光看視頻是不管用的,一定要自己動手做!切記不要照著抄代碼)。

有興趣的同學可以去慕課網看看(並非廣告):http://www.imooc.com/learn/300

自訂控制項這個玩意呢,就得考多練,於是又寫了一個抽屜效果的菜單,也是比較簡單的。

老規矩,先上:


那麼中間的圓圈就是衛星菜單拉,而左下角的呢,是抽屜菜單。

下面進入正題:

自訂Viewgroup的一般步驟:

寫構造器,重寫onMeasure(),重寫onLayout();

由於本篇部落格是viewgroup初步,故全部從最簡單的開始。 我們來講抽屜菜單。

首先建立DrawerMenu類,使他繼承於ViewGroup

public class DrawerMenu extends ViewGroup

然後添加三個構造器,使用一般的方法,少參數的調用多參數的:

public DrawerMenu(Context context) {        this(context, null);    }    public DrawerMenu(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public DrawerMenu(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }
一般在第三個構造器裡,我們會使用TypedArray來獲得他對應attr.xml裡面的屬性,這裡為了簡單,不給這個viewgroup添加任何自訂屬性,所以構造器這樣就可以。

接下來是重寫onMeasure()方法。所謂Measure為測量view的大小

 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int count = getChildCount();        for (int i = 0; i < count; i++) {            measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);        }        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }

測量模式一共分三種,這裡也不多介紹了。因為我們的子view都是wrap_content的,所以我們只要簡單測量一下即可。


接下來是關鍵的地方,onLayout(), 此方法是為子view進行布局。告訴子view他應該在什麼位置,首先,我們要布局主按鈕,這裡我們將它固定在左下角:

protected void onLayout(boolean changed, int l, int t, int r, int b) {            layoutBottom();}
    private void layoutBottom() {        mButton_buttom = getChildAt(0);        mButton_buttom.setOnClickListener(this);        mWidth_button_buttom = mButton_buttom.getMeasuredWidth();        mHeight_button_buttom = mButton_buttom.getMeasuredHeight();        mButtonX = 0;        mButtonY = getMeasuredHeight() - mHeight_button_buttom;        mButton_buttom.layout(mButtonX, mButtonY, mWidth_button_buttom, getMeasuredHeight());    }


主要的button 是第一個子view 。我們用getChildAt(index=0)來獲得, 然後擷取得到的測量好的寬和高.

最後將主按鈕layout到合適的位置,


layout裡面四個參數為畫出圓圈地方的x,y

所以 左上方一點的位置為: 0,height - cHeight  右下角的座標為   cWidth,height

這樣我們便確定了主button的位置。


那麼接下來當然是去layout 子view的位置了。相信大家也明白了,子view的位置只要找出座標就好。所以我們這裡繼續確定子view的位置。

protected void onLayout(boolean changed, int l, int t, int r, int b) {        Log.i("wing", mIsChanged + "");        if (mIsChanged) {            layoutBottom();            int count = getChildCount();            for (int i = 0; i < count - 1; i++) {                View child = getChildAt(i + 1);                int childWidth = child.getMeasuredWidth();                int childHeight = child.getMeasuredHeight();                child.layout(0, mButtonY - mHeight_button_buttom * (i + 1) * 2, childWidth, getMeasuredHeight());                child.setVisibility(GONE);            }        }    }

然後我們為主按鈕添加監聽: 來切換菜單的狀態,如果菜單為關閉,那麼按下的時候顯示按鈕,如果為開啟,那麼將按鈕都GONE。

這裡為按鈕添加了動畫效果,如果你還不瞭解安卓動畫,那麼看看這裡:http://blog.csdn.net/wingichoy/article/details/47104433

為了好看呢,我們給每個動畫的duration加了 i*100的延遲來有漸層的效果

    public void onClick(View v) {        toggleMenu();    }
 private void toggleMenu() {        if (mIsChanged) {            int count = getChildCount();            for (int i = 0; i < count - 1; i++) {                View child = getChildAt(i + 1);                TranslateAnimation ta = new TranslateAnimation(-child.getMeasuredWidth(), 0, 0, 0);                ta.setDuration(1000 + i * 100);                child.startAnimation(ta);                child.setVisibility(VISIBLE);                mIsChanged = false;            }        } else {            int count = getChildCount();            for (int i = 0; i < count - 1; i++) {                View child = getChildAt(i + 1);                TranslateAnimation ta = new TranslateAnimation(0, -child.getMeasuredWidth(), 0, 0);                ta.setDuration(1000 + i * 100);                child.startAnimation(ta);                child.setVisibility(GONE);                mIsChanged = true;            }        }


這下我們的viewgroup基本大功告成了。添加到mainactivity的xml上來試試

 <com.wingsoft.arcmenu.DrawerMenu        android:layout_width="match_parent"        android:layout_height="match_parent">        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:src="@drawable/drawer"/>        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:src="@drawable/drawer"/>        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:src="@drawable/drawer"/>        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:src="@drawable/drawer"/>        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:src="@drawable/drawer"/>    </com.wingsoft.arcmenu.DrawerMenu>


嗯。不錯。  樣子也實現了。 那麼接下來大家動動腦筋,自己寫個監聽器吧~ 今天就到這裡。

如果肯努力,技術很快就趕上來了~~

著作權聲明:本文為博主原創文章,歡迎註明出處後轉載。

android自訂viewgroup初步之一----抽屜菜單

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.