zoukankan      html  css  js  c++  java
  • Android 实现卫星菜单(精简版)

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
        private ArcDemo mArc;
        private ListView mListView;
        private List<String> mData;
        private ArrayAdapter mAdapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mArc = (ArcDemo) findViewById(R.id.view_arc);
            mArc.setOnSubItemClickListener(new ArcDemo.onSubItemClickListener() {
                @Override
                public void onItemClick(View view, int position) {
                    Toast.makeText(MainActivity.this, "position" + position, Toast.LENGTH_SHORT).show();
                }
            });
    
            initListView();
        }
    
        private void initListView() {
            mListView = (ListView) findViewById(R.id.listview);
            mData = new ArrayList<String>();
            for (int i = 'A'; i <= 'z'; i++) {
                mData.add((char) i + "");
            }
            mAdapter = new ArrayAdapter<String>(
                    MainActivity.this, android.R.layout.simple_list_item_1, mData);
            mListView.setAdapter(mAdapter);
    
            mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
    
                }
    
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    if (mArc.isOpen()) {
                        mArc.subItemAnim();
                    }
                }
            });
        }
    }

    ArcDemo.java

    public class ArcDemo extends ViewGroup {
        private View mButton;
        private BStatus mBStatus = BStatus.STATUS_CLOSE;
        private onSubItemClickListener onListener;
    
        public enum BStatus {
            STATUS_OPEN, STATUS_CLOSE
        }
    
        //子菜单点击接口
        public interface onSubItemClickListener {
            void onItemClick(View view, int position);
        }
    
        public void setOnSubItemClickListener(onSubItemClickListener mListener) {
            this.onListener = mListener;
        }
    
        public ArcDemo(Context context) {
            super(context);
    //        this(context, null);
        }
    
        public ArcDemo(Context context, AttributeSet attrs) {
            super(context, attrs);
    //        this(context, attrs, 0);
        }
    
        public ArcDemo(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        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
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            if (changed) {
                //主菜单按钮
                onMainButton();
                //子菜单按钮
                onSubItemButton();
            }
        }
    
        //获取主菜单按钮
        private void onMainButton() {
            mButton = getChildAt(0);
            mButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    //主菜单动画
                    Animation rotateAnim = AnimationUtils.loadAnimation(getContext(), R.anim.anim);
                    mButton.startAnimation(rotateAnim);
    
                    //子菜单动画
                    subItemAnim();
                }
            });
            int l, t, r = 0, b = 0;
            int mWidth = mButton.getMeasuredWidth();
            int mHeight = mButton.getMeasuredHeight();
    
            l = getMeasuredWidth() - mWidth;
            t = getMeasuredHeight() - mHeight;
    
            mButton.layout(l, t, getMeasuredWidth(), getMeasuredHeight());
        }
    
        //获取子菜单按钮
        private void onSubItemButton() {
            int count = getChildCount();
            for (int i = 0; i < count - 1; i++) {
                View childView = getChildAt(i + 1);
    
                //开始时不呈现子菜单
                childView.setVisibility(View.GONE);
    
                int radius = 350;
                int cl, ct, cr, cb;
    
                cr = (int) (radius * Math.sin(Math.PI / 2 / (count - 2) * i));
                cb = (int) (radius * Math.cos(Math.PI / 2 / (count - 2) * i));
    
                int cWidth = childView.getMeasuredWidth();
                int cHeight = childView.getMeasuredHeight();
    
                cl = getMeasuredWidth() - cWidth - cr;
                ct = getMeasuredHeight() - cHeight - cb;
    
                //layout(l,t,r,b);前两参数决定位置,后两参数决定大小
                //参数(1,t)为View控件的左上角坐标
                // (r-l,b-t)为View控件大小,r-l为控件宽度,b-t为控件高度
                childView.layout(cl, ct, getMeasuredWidth() - cr, getMeasuredHeight() - cb);
            }
        }
    
        //子菜单散开回笼动画
        public void subItemAnim() {
            int count = getChildCount();
            for (int i = 0; i < count - 1; i++) {
                final View cView = getChildAt(i + 1);
    
                //点击主菜单后,子菜单就立刻呈现,否则后面的动画无法完成
                cView.setVisibility(VISIBLE);
    
                int radius = 350;
                int l, t, r, d;
    
                r = (int) (radius * Math.sin(Math.PI / 2 / (count - 2) * i));
                d = (int) (radius * Math.cos(Math.PI / 2 / (count - 2) * i));
    
    //            int cWidth = cView.getMeasuredWidth();
    //            int cHeight = cView.getMeasuredHeight();
    //
    //            l = getMeasuredWidth() - cWidth - r;
    //            t = getMeasuredHeight() - cHeight - d;
    
                AnimationSet set = new AnimationSet(true);
                Animation tranAnim = null;
                if (mBStatus == BStatus.STATUS_CLOSE) {
                    //散开动画
                    tranAnim = new TranslateAnimation(r, 0, d, 0);
                    cView.setClickable(true);
                    cView.setFocusable(true);
                } else {
                    //回笼动画
                    tranAnim = new TranslateAnimation(0, r, 0, d);
                    cView.setClickable(false);
                    cView.setFocusable(false);
                }
                tranAnim.setDuration(300);
    //            tranAnim.setFillAfter(true);  //让最后一帧的动画不消失
                tranAnim.setStartOffset(100 * i / count);
                tranAnim.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {
    
                    }
    
                    @Override
                    public void onAnimationEnd(Animation animation) {
                        if (mBStatus == BStatus.STATUS_CLOSE) {
                            cView.setVisibility(GONE);
                        }
                    }
    
                    @Override
                    public void onAnimationRepeat(Animation animation) {
    
                    }
                });
    
    
                Animation rotateAnim = new RotateAnimation(
                        0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
                rotateAnim.setDuration(300);
    //            rotateAnim.setFillAfter(false);
    
                set.addAnimation(rotateAnim);
                set.addAnimation(tranAnim);
                cView.startAnimation(set);
    
                //散开后子菜单的点击监听事件
                final int pos = i + 1;
                cView.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (onListener != null) {
                            onListener.onItemClick(cView, pos);
                        }
                        //散开后点击子菜单动画
                        subItemClickAnim(pos - 1);
                        changStatus();
                    }
                });
            }
            changStatus();
        }
    
        //监听子菜单状态改变
        private void changStatus() {
            mBStatus = (mBStatus == BStatus.STATUS_CLOSE ? BStatus.STATUS_OPEN : BStatus.STATUS_CLOSE);
        }
    
        //散开后点击子菜单动画
        private void subItemClickAnim(int pos) {
            int count = getChildCount();
            for (int i = 0;i<count-1;i++) {
                View cView = getChildAt(i+1);
                if(i == pos) {
                    //变大,变透明
                    cView.startAnimation(toBig());
                }
                else {
                    //变小,变透明
                    cView.startAnimation(toSmall());
                }
                cView.setClickable(false);
                cView.setFocusable(false);
            }
        }
    
        //变大,变透明
        private Animation toBig(){
            Animation big = AnimationUtils.loadAnimation(getContext(), R.anim.bigalpha);
            return big;
        }
    
        //变小,变透明
        private Animation toSmall(){
            Animation small = AnimationUtils.loadAnimation(getContext(),R.anim.smallalpha);
            return small;
        }
    
        //给ListView调用
        public boolean isOpen() {
            return mBStatus == BStatus.STATUS_OPEN;
        }
    
    }

    activity_main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <ListView
            android:id="@+id/listview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
        <my.com.example.x550v.view.ArcDemo
            android:id="@+id/view_arc"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/composer_button">
    
                <ImageView
                    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_camera" />
    
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/composer_with" />
    
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/composer_thought" />
    
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/composer_music" />
    
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/composer_place" />
    
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/composer_sleep" />
        </my.com.example.x550v.view.ArcDemo>
    </RelativeLayout>

    anim.xml

    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <rotate
            android:duration="300"
            android:fromDegrees="0"
            android:toDegrees="360"
            android:pivotX="50%"
            android:pivotY="50%"/>
    </set>

    bigalpha.xml

    <!--android:fillAfter="true"得加,取动画结束后的最后一帧-->
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillAfter="true">
        <alpha
            android:duration="200"
            android:fromAlpha="1"
            android:toAlpha="0"/>
        <scale
            android:duration="200"
            android:fromXScale="1"
            android:fromYScale="1"
            android:toXScale="3"
            android:toYScale="3"
            android:pivotX="50%"
            android:pivotY="50%" />
    </set>

    smallalpha.xml

    <!--android:fillAfter="true"得加,取动画结束后的最后一帧-->
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillAfter="true">
        <alpha
            android:duration="200"
            android:fromAlpha="1"
            android:toAlpha="0"/>
        <scale
            android:duration="200"
            android:fromXScale="1"
            android:fromYScale="1"
            android:toXScale="0"
            android:toYScale="0"
            android:pivotX="50%"
            android:pivotY="50%" />
    </set>

    运行效果:

  • 相关阅读:
    React组件的Refs
    Typechecking With PropTypes
    酷炫Jquery收集
    JSTL函数标签库 fn标签学习
    Struts标签 比较时间大小
    Struts2 拦截器 配置IFrame页面跳转
    实体Bean, Entity 注解设置
    Uploadify 参数说明
    Uploadify jsp使用示例
    百度umeditor
  • 原文地址:https://www.cnblogs.com/tianhengblogs/p/5265195.html
Copyright © 2011-2022 走看看