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

jopen 8年前發布 | 8K 次閱讀 Android開發 移動開發

自定義控件這個玩意呢,就得考多練,于是又寫了一個抽屜效果的菜單,也是比較簡單的。

老規矩,先上效果圖:


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

下面進入正題:

自定義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>


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

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

來自: http://blog.csdn.net/wingichoy/article/details/47832151

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!