ArcMenu

54124 단어 android
ArcMenu:
사용자 정의 속성//attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!--            -->
    <!--             -->
    <attr name="position">
        <enum name="left_top" value="0" />
        <enum name="left_bottom" value="1" />
        <enum name="right_top" value="2" />
        <enum name="right_bottom" value="3" />
    </attr>
    <!--             -->
    <attr name="radius" format="dimension" />

    <!--                    -->
    <declare-styleable name="ArcMenu">
        <attr name="position" />
        <attr name="radius" />
    </declare-styleable>

</resources>

테스트 읽 기 속성:사용자 정의 컨트롤,사용자 정의 속성 사용
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:myapp="http://schemas.android.com/apk/res/com.example.hendry_arcmenu"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.hendry_arcmenu.view.ArcMenu
        android:id="@+id/id_arcmenu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        myapp:position="right_top"
        myapp:radius="200sp" >
    </com.example.hendry_arcmenu.view.ArcMenu>

</RelativeLayout>

구조 함수 에서 속성 읽 기/ArcMenu.xml
    public ArcMenu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
                R.styleable.ArcMenu, defStyleAttr, 0);
        int default_radius = (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_SP, 100, context.getResources()
                        .getDisplayMetrics());
//      mRadius = a.getDimensionPixelSize(R.styleable.ArcMenu_radius,
//              default_radius);
        mRadius = (int) a.getDimension(R.styleable.ArcMenu_radius, default_radius);
        int pos = a.getInt(R.styleable.ArcMenu_position, RIGHT_BOTTOM);
        switch (pos) {
        case LEFT_TOP:
            mPosition = position.LEFT_TOP;
            break;
        case LEFT_BOTTOM:
            mPosition = position.LEFT_BOTTOM;
            break;
        case RIGHT_TOP:
            mPosition = position.RIGHT_TOP;
            break;
        case RIGHT_BOTTOM:
            mPosition = position.RIGHT_BOTTOM;
            break;
        }
        a.recycle();
        Log.i("hendry_arcmenu__", "position:" + mPosition + " radius:"
                + mRadius);
    }

OnMeasure 는 서브 View 의 너비 와 높이 를 측정 하고 컨트롤 자체 의 너비 와 높이 를 설정 합 니 다.
일반적으로 사용자 정의 view 는super.onMeasure(widthMeasureSpec, heightMeasureSpec);이 문장 만 호출 하면 됩 니 다.onMeasure 는 이 사용자 정의 컨트롤 이 레이아웃 파일 에 설 치 된 설정 에 따라 너비 와 높이 를 확인 합 니 다.
ViewGroup 을 사용자 정의 하려 면 각 하위 view 를 측정 해 야 합 니 다.
측정 하기 전에 이 컨트롤 의 레이아웃 파일 을 작성 해 야 합 니 다.이 컨트롤 내부 에 어떤 하위 view 가 있 는 지 확인 해 야 측정 을 시작 할 수 있 습 니 다.하위 view 는 그림 자원 등 을 사용 하여 해당 디 렉 터 리 에 복사 해 야 합 니 다.
이 ArcMenu 컨트롤 은 다른 컨트롤 위 에 덮 여 있 으 며 화면의 4 개의 뿔 에 놓 을 수 있 기 때문에 전체 화면 컨트롤 입 니 다.레이아웃 파일 의 너비 와 높이 는 match 로 설정 되 어 있 습 니 다.parent
첫 번 째 메 인 단 추 는 바깥 테두리+내부 에 있 는 그림 을 조합 한 것 입 니 다.그림 회전 애니메이션 을 편리 하 게 하기 위해 서 입 니 다.메 인 단 추 를 제외 하고 다른 단 추 는 모두 그림 상자 ImageView 입 니 다.
복사 onMeasure 방법 은 최종 적 으로 부모 류 set Measured Dimension 방법 을 호출 하거나 우리 가 복사 할 때 전달 폭 이 높 고 set Measured Dimension 방법 을 호출 합 니 다.이 방법 은 전달 하 는 매개 변 수 를 mMeasured Width,mMeasured Height 에 부여 하 는 것 이 주요 역할 입 니 다.즉,우리 가 사용자 정의 컨트롤 의 너비 와 높이 를 확정 한 것 입 니 다.그래서 onMeasure 방법 이 실 행 된 후에...우 리 는 getMeasured Width,getMeasured Height 방법 으로 사용자 정의 컨트롤 을 측정 하여 얻 은 너비 와 높이 를 얻 을 수 있 습 니 다.
viewgroup 의 경우 모든 하위 view 에 measure Child 방법 을 옮 겨 다 녀 야 합 니 다.매개 변 수 는 똑 같 습 니 다.모두 widthMeasure Spec 과 height Measure Spec 입 니 다.이때 measure Child 방법 에 서 는 전 달 된 Measure Spec 매개 변수 에 따라 하위 view 에 대응 하 는 child WidthMeasure Spec 과 child Height Measure Spec 를 생 성 하기 때 문 입 니 다.그리고 child.measure(childWidthMeasureSpec,childHeightMeasureSpec)를 호출 합 니 다.이 방법 은 매우 복잡 해 보이 는데 모두 MeasureSpec 에 대한 계산 이 고 cache 도 있 지만 결국은 set Measured Dimension 방법 을 사용 하여 이 하위 view 의 너비 와 높이 를 설정 합 니 다.
이 를 통 해 알 수 있 듯 이 MeasureSpec 은 중간 변수 와 같 습 니 다.측정 에 필요 한 데 이 터 를 전달 하 는 데 주요 역할 을 합 니 다.32 비트 의 int 값 이 고 높 은 2 비트 는 SpecMode 측정 모델 을 대표 하 며 낮은 30 비트 는 SpecSize 를 대표 합 니 다.특정한 측정 모델 에서 의 규격 크기 를 말 합 니 다.
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            //      ???     ,   measureChild     MeasureSpec
// getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
            measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

onLayout
onLayout 는 layot 를 먼저 말 해 야 합 니 다.layot 방법 은 컨트롤 자체 의 위 치 를 확인 하 는 것 이 고 layot 방법 에 서 는 onLayout 방법 을 사용 하여 하위 요소 의 위 치 를 확인 합 니 다.
따라서 사용자 정의 ViewGroup 은 하위 요소 의 위 치 를 확인 하기 위해 onLayout 를 다시 써 야 합 니 다.시스템 은 layot 방법 을 자동 으로 호출 하여 다시 쓴 onLayout 가 호출 됩 니 다.
onLayout 의 기능 은 부모 용기 에서 하위 요소 의 위 치 를 확인 하 는 것 입 니 다.View 와 ViewGroup 은 모두 onLayout 방법 을 진정 으로 실현 하지 못 했 습 니 다.사용자 정의 컨트롤 서브 view 위치 가 확실 하지 않 기 때문에 사용자 정의 로 위 치 를 확인 해 야 합 니 다.따라서 계승 하 는 ViewGroup 이 라면 onLayout 를 복사 할 때 슈퍼.onLayout 방법 을 호출 하 는 것 은 존재 하지 않 습 니 다.스스로 onLayout 를 실현 해 야 합 니 다.onLayout 방법 에서 layot 방법 을 호출 하여 하위 view 에 위 치 를 지정 합 니 다.
모든 View 컨트롤 이 onLayout 를 실현 하지 못 한 것 은 아 닙 니 다.예 를 들 어 사용자 정의 컨트롤 이 Horizontal ScrollView 에서 계승 되면 부모 클래스 의 onLayoutsuper.onLayout(changed, l, t, r, b);를 호출 해 야 합 니 다.
방금 말 했 듯 이 onLayout 방법 은 최종 적 으로 View.layot 방법 을 호출 하여 하위 view 위 치 를 확인 해 야 합 니 다.onLayout 방법 이 호출 된 이 유 는 View.layot 방법 에서 change 를 판단 하고 onLayout(changed,l,t,r,b)를 다시 호출 하기 때 문 입 니 다.
결국 View.layot 방법 은 컨트롤 에 위 치 를 정 합 니 다.이 컨트롤 에 하위 컨트롤 이 있 으 면 이 컨트롤 의 onLayout 방법 을 호출 합 니 다.onLayout 방법 은 중성자 컨트롤 이 자신의 layot 방법 을 호출 합 니 다.하위 컨트롤 아래 에 하위 컨트롤 이 있 으 면 layot 방법 이 호출 될 때 changed 변 수 를 검사 하고 해당 하 는 onLayout 를 실행 하여 하위 view 를 찾 습 니 다.그래서 이렇게 층 층 이 전달 된다.
이 를 통 해 알 수 있 듯 이 View.layot 방법 은 먼저 컨트롤 자체 에 대한 포 지 셔 닝 을 한 다음 onLayout 를 호출 하여 하위 컨트롤 에 대한 포 지 셔 닝 을 합 니 다.onLayout 실행 과정 에서 하위 컨트롤 에 대응 하 는 layot 방법 을 호출 합 니 다.layot 실행 중 하위 컨트롤 에 하위 컨트롤 이 있 는 것 을 발견 하면 onLayout 를 호출 하여 하위 컨트롤 을 확인 합 니 다.
다시 말 하면 우리 가 다시 쓴 View Group 의 onLayout 를 호출 할 때 우리 가 해 야 할 일 은 하위 요 소 를 옮 겨 다 니 며 layot 방법 을 호출 하 는 것 입 니 다.만약 에 이 하위 요소 아래 에 하위 요소 가 있다 면 onLayout 방법 을 다시 호출 하 는 것 입 니 다.이렇게 view 아래 의 하위 view 는 포 지 셔 닝 을 받 았 습 니 다.또한 View Group 은 원래 onLayout 를 제공 하지 않 았 습 니 다.우리 가 복사 한 onLayout 는 View Group 의 View.layot 가 실행 되 었 기 때문에 복사 한 onLayout 가 호출 되 었 습 니 다.따라서 슈퍼.onLayout()가 없 으 면 view Group 의 포 지 셔 닝 이 실행 되 지 않 아 도 됩 니 다.android.view.View.layout(int l, int t, int r, int b)
4 개의 매개 변 수 는 left,top,right,bottom 에 대응 하 는 것 이 보통mCButton.layout(l, t, l + width, t + width);입 니 다.
//attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!--            -->
    <!--             -->
    <attr name="position">
        <enum name="left_top" value="0" />
        <enum name="left_bottom" value="1" />
        <enum name="right_top" value="2" />
        <enum name="right_bottom" value="3" />
    </attr>
    <!--             -->
    <attr name="radius" format="dimension" />

    <!--                    -->
    <declare-styleable name="ArcMenu">
        <attr name="position" />
        <attr name="radius" />
    </declare-styleable>

</resources>

//activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:myapp="http://schemas.android.com/apk/res/com.example.hendry_arcmenu" android:layout_width="match_parent" android:layout_height="match_parent" >

    <ListView  android:id="@+id/id_listview" android:layout_width="match_parent" android:layout_height="match_parent" >
    </ListView>

    <com.example.hendry_arcmenu.view.ArcMenu  android:id="@+id/id_arcmenu" android:layout_width="match_parent" android:layout_height="match_parent" myapp:position="left_bottom" myapp:radius="120dp" >

        <RelativeLayout  android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/composer_button" >

            <ImageView  android:id="@+id/id_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@drawable/composer_icn_plus" />
        </RelativeLayout>

        <ImageView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/composer_music" android:tag="Music" />

        <ImageView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/composer_place" android:tag="Place" />

        <ImageView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/composer_sleep" android:tag="Sleep" />

        <ImageView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/composer_thought" android:tag="Sun" />

        <ImageView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/composer_with" android:tag="People" />
    </com.example.hendry_arcmenu.view.ArcMenu>

</RelativeLayout>

//MainActivity.java
package com.example.hendry_arcmenu;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.example.hendry_arcmenu.view.ArcMenu;
import com.example.hendry_arcmenu.view.ArcMenu.OnMenuItemClickListener;

public class MainActivity extends Activity {

    private ListView mListView;
    private ArcMenu mArcMenu;
    private List<String> mData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initData();
        initViews();
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, mData);
        mListView.setAdapter(adapter);
        initEvents();
    }

    private void initEvents() {
        // ListView      arcMenu
        mListView.setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {
                if (mArcMenu.isOpen()) {
                    mArcMenu.toggleMenu(600);
                }

            }
        });

        // arcMenu          
        mArcMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {

            @Override
            public void onClick(View view, int pos) {
                Toast.makeText(
                        MainActivity.this,
                        "you clicked item getTag: " + view.getTag() + " , pos:"
                                + pos, Toast.LENGTH_SHORT).show();
            }
        });

    }

    private void initViews() {
        mListView = (ListView) findViewById(R.id.id_listview);
        mArcMenu = (ArcMenu) findViewById(R.id.id_arcmenu);
    }

    private void initData() {
        mData = new ArrayList<String>();
        //             char        
        for (int i = 'A'; i < 'Z'; i++) {
            mData.add((char) i + "     "); //    char       
        }
    }

}

ArcMenu 에 잘 모 르 는 것 이 있 습 니 다.바로 onLayout 에 child.setVisibility(View.GONE)가 설치 되 어 있 는 것 을 제외 하고.이 곳 을 제외 하고 하위 메뉴 항목 을 숨 길 수 있 습 니 다.애니메이션 을 설정 할 때 메뉴 애니메이션 을 닫 고 child.setVisibility 를 GONE 로 설정 하면 소 용이 없습니다.toggleMenu 에 서 는 처음부터 childView 를 설정 합 니 다.setVisibility(View.VISIBLE);여기 주석 이 떨어져 도 아무런 영향 이 없 는데..................................................
onLayout 설정 을 숨 긴 후 애니메이션 의 setFillAfter 설정 으로 만 하위 메뉴 항목 이 표시 되 는 지 여 부 를 제어 할 수 있 습 니 다.setVisibility 는 적용 되 지 않 습 니 다.그러나 원래 코드 를 보면 이 방법 이 아니 라 setVisibility 로 하위 메뉴 항목 이 표시 되 는 지 여 부 를 제어 할 수 있 습 니 다.
//ArcMenu.java
package com.example.hendry_arcmenu.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AlphaAnimation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;

import com.example.hendry_arcmenu.R;

public class ArcMenu extends ViewGroup implements OnClickListener {
    /** *            */

    private enum position {
        LEFT_TOP, LEFT_BOTTOM, RIGHT_TOP, RIGHT_BOTTOM
    };

    private static final int LEFT_TOP_VAL = 0;
    private static final int LEFT_BOTTOM_VAL = 1;
    private static final int RIGHT_TOP_VAL = 2;
    private static final int RIGHT_BOTTOM_VAL = 3;

    private int mRadius;
    private position mPosition = position.RIGHT_BOTTOM;

    private enum status {
        OPEN, CLOSED
    };

    private status mStatus = status.CLOSED;

    private OnMenuItemClickListener mMenuItemClickListener;

    /** *            */

    public interface OnMenuItemClickListener {
        void onClick(View view, int pos);
    }

    public void setOnMenuItemClickListener(OnMenuItemClickListener listener) {
        mMenuItemClickListener = listener;
    }

    public ArcMenu(Context context) {
        this(context, null);
    }

    public ArcMenu(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ArcMenu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
                R.styleable.ArcMenu, defStyleAttr, 0);
        int default_radius = (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_SP, 100, context.getResources()
                        .getDisplayMetrics());
        // mRadius = a.getDimensionPixelSize(R.styleable.ArcMenu_radius,
        // default_radius);
        mRadius = (int) a.getDimension(R.styleable.ArcMenu_radius,
                default_radius);
        int pos = a.getInt(R.styleable.ArcMenu_position, RIGHT_BOTTOM_VAL);
        switch (pos) {
        case LEFT_TOP_VAL:
            mPosition = position.LEFT_TOP;
            break;
        case LEFT_BOTTOM_VAL:
            mPosition = position.LEFT_BOTTOM;
            break;
        case RIGHT_TOP_VAL:
            mPosition = position.RIGHT_TOP;
            break;
        case RIGHT_BOTTOM_VAL:
            mPosition = position.RIGHT_BOTTOM;
            break;
        }
        a.recycle();
        Log.i("hendry_arcmenu__", "position:" + mPosition + " radius:"
                + mRadius);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            //       ???     ,   measureChild     MeasureSpec
            // getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
            measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (changed) {
            layoutCButton();
            //             
            int count = getChildCount();

            for (int i = 0; i < count - 1; i++) {
                //   i + 1    ,             
                View child = getChildAt(i + 1);
                //         
                child.setVisibility(View.GONE);
                //          left, top
                int cl = (int) (mRadius * Math.sin(i
                        * (Math.PI / 2 / (count - 2))));
                int ct = (int) (mRadius * Math.cos(i
                        * (Math.PI / 2 / (count - 2))));
                int cWidth = child.getMeasuredWidth();
                int cHeight = child.getMeasuredHeight();
                switch (mPosition) {
                case LEFT_TOP:

                    break;
                case LEFT_BOTTOM:

                    ct = getMeasuredHeight() - ct - cHeight;
                    break;
                case RIGHT_TOP:
                    cl = getMeasuredWidth() - cl - cWidth;
                    break;
                case RIGHT_BOTTOM:
                    cl = getMeasuredWidth() - cl - cWidth;
                    ct = getMeasuredHeight() - ct - cHeight;
                    break;
                }
                child.layout(cl, ct, cl + cWidth, ct + cHeight);
            }
        }
    }

    private void layoutCButton() {
        //              CButton

        View CButton = getChildAt(0);

        //   CButton     
        CButton.setOnClickListener(this);

        //             
        int width = CButton.getMeasuredWidth();
        int height = CButton.getMeasuredHeight();

        //               
        int l = 0;
        int t = 0;
        switch (mPosition) {
        case LEFT_TOP:
            l = 0;
            t = 0;
            break;
        case LEFT_BOTTOM:
            l = 0;
            // getMeasuredHeight             getMeasuredWidth      
            t = getMeasuredHeight() - height;
            break;
        case RIGHT_TOP:
            l = getMeasuredWidth() - width;
            t = 0;
            break;
        case RIGHT_BOTTOM:
            l = getMeasuredWidth() - width;
            t = getMeasuredHeight() - height;
            break;
        }

        //   layout         
        CButton.layout(l, t, l + width, t + height);

    }

    @Override
    public void onClick(View v) {
        // CButton  setOnClickListener ,        CButton        view    
        rotateCButton(v, 0f, 360f, 300);

        toggleMenu(300);
    }

    /** *          view            * * @param duration */
    public void toggleMenu(int duration) {

        int count = getChildCount();
        //      CButton    ,          ,        ,             ,           
        int margin = ( getChildAt(0).getMeasuredWidth() - getChildAt(1).getMeasuredWidth()) /2 ;

        //      CButton
        //   for              ,           ,               
        for (int i = 0; i < count - 1; i++) {
            //      view  
            final View childView = getChildAt(i + 1);
            childView.setVisibility(View.VISIBLE);
            //     ,               , 0, 0        ,             

            //  mRadius        ,           CButton         ,                ,            
             int deltaX = (int) (mRadius * Math.sin(i
             * (Math.PI / 2 / (count - 2))) - margin);
             int deltaY = (int) (mRadius * Math.cos(i
             * (Math.PI / 2 / (count - 2))) - margin);


            //    to open  ,       layout   ,              
            //      close ,         ,                 
            //             , X                         ,
            //   X        ,               0
            // X   ,     ,     
            // Y         ,     ..               ,               
            //        ,       ,     ,     (-1),   (-1),    sin, cos
            //          , X  (-1), Y  
            //     X  ,Y  (-1)
            //     X   ,Y  
            //    4                 
            int xflag = 1;
            int yflag = 1;
            switch (mPosition) {
            case LEFT_TOP:
                xflag = -1;
                yflag = -1;
                break;
            case LEFT_BOTTOM:
                xflag = -1;
                yflag = 1;
                break;
            case RIGHT_TOP:
                xflag = 1;
                yflag = -1;
                break;
            case RIGHT_BOTTOM:
                xflag = 1;
                yflag = 1;
                break;
            }

            // TranslateAnimation transAn = null;
            Animation transAn = null;
            if (mStatus == status.CLOSED) { //     
                //           ,           
                transAn = new TranslateAnimation(deltaX * xflag, 0, deltaY
                        * yflag, 0);

                //      
                childView.setFocusable(true);
                childView.setClickable(true);

            } else { //     
                //      ,             ,                    ,            if  

                transAn = new TranslateAnimation(0, deltaX * xflag, 0, deltaY
                        * yflag);
                //               ,    ,           ,      ,        GONE ,
                //          ,        ,          ,            
                childView.setClickable(false);
                childView.setFocusable(false);
            }

            transAn.setFillAfter(true);
            transAn.setDuration(duration);
            //            
            transAn.setStartOffset((i * 100) / count);

            //     
            RotateAnimation rotateAnim = new RotateAnimation(0, 720,
                    Animation.RELATIVE_TO_SELF, 0.5f,
                    Animation.RELATIVE_TO_SELF, 0.5f);
            rotateAnim.setDuration(duration);
            rotateAnim.setFillAfter(true);

            AnimationSet anSet = new AnimationSet(true);
            anSet.addAnimation(rotateAnim);
            anSet.addAnimation(transAn);
            // childView.startAnimation(rotateAnim);
            // childView.startAnimation(transAn);
            // childView.startAnimation(anSet);

            /** *  view   visibility GONE   ,          */
            if (mStatus == status.CLOSED) {
                anSet.setFillAfter(true); // animationSet       fillAfter
                                            //        
            } else {
                //            
                AlphaAnimation alphaAni = new AlphaAnimation(1.0f, 0.5f);
                anSet.addAnimation(alphaAni);

                anSet.setFillAfter(false);
            }
            anSet.setAnimationListener(new AnimationListener() {

                @Override
                public void onAnimationStart(Animation animation) {
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }

                /** *            ? */
                @Override
                public void onAnimationEnd(Animation animation) {
                    if (mStatus == status.CLOSED) {
                        childView.setVisibility(View.GONE);
                    }
                }
            });
            childView.startAnimation(anSet);

            /** *            */
            final int pos = i + 1; //           i + 1    CButton
            childView.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    //             
                    if (null != mMenuItemClickListener) {
                        mMenuItemClickListener.onClick(v, pos);
                    }
                    //         , pos -1        ,    CButton 0
                    menuItemAnim(pos - 1);
                    //       ,          
                    changeStatus();

                }
            });
        }

        //          
        changeStatus();
        Log.i("MYTAG", "mStatus : " + mStatus);
    }

    private void changeStatus() {
        mStatus = (mStatus == status.CLOSED ? status.OPEN : status.CLOSED);
    }

    /** *       , pos  0                       ,        ,                */
    protected void menuItemAnim(int pos) {
        int count = getChildCount();
        for (int i = 0; i < count - 1; i++) {
            View child = getChildAt(i + 1);
            if (pos == i) {
                //   
                child.startAnimation(scaleBigAni(500));
            } else {
                //   
                child.startAnimation(scaleSmallAnimation(500,0.0f));
            }
            //         
            child.setClickable(false);
            child.setFocusable(false);
        }

    }

    private Animation scaleBigAni(int duration) {
        AnimationSet animationSet = new AnimationSet(true);
        //   4 
        ScaleAnimation scaleAnim = new ScaleAnimation(1.0f, 4.0f, 1.0f, 4.0f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        //       
        AlphaAnimation alphaAnim = new AlphaAnimation(1f, 0.0f);

        animationSet.addAnimation(scaleAnim);
        animationSet.addAnimation(alphaAnim);

        animationSet.setDuration(duration);
        animationSet.setFillAfter(true);
        return animationSet;
    }

    private Animation scaleSmallAnimation(int duration , float toScale) {
        AnimationSet animationSet = new AnimationSet(true);

        ScaleAnimation scaleAnim = new ScaleAnimation(1.0f, toScale, 1.0f, toScale,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        AlphaAnimation alphaAnim = new AlphaAnimation(1.f, 0.0f);

        animationSet.addAnimation(scaleAnim);
        animationSet.addAnimation(alphaAnim);

        animationSet.setDuration(duration);
        animationSet.setFillAfter(true);

        return animationSet;
    }

    private void rotateCButton(View v, float start, float end, int duration) {
        RotateAnimation anima = new RotateAnimation(start, end,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        anima.setDuration(duration);
        anima.setFillAfter(true); //             
        v.startAnimation(anima);
    }

    public Boolean isOpen() {
        return mStatus == status.OPEN;
    }
}

좋은 웹페이지 즐겨찾기