美文网首页自定义控件
Android 带有弹出收缩动画的扇形菜单

Android 带有弹出收缩动画的扇形菜单

作者: 小桃子123 | 来源:发表于2017-06-26 16:37 被阅读0次
    扇形菜单动画.gif
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        private ImageView imgPublish;
        private TextView textView1;
        private TextView textView2;
    
        private boolean isMenuOpen = false;
    
        private List<TextView> textViews = new ArrayList<>();
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            imgPublish = (ImageView) findViewById(R.id.img_publish);
            textView1 = (TextView) findViewById(R.id.tv_1);
            textView2 = (TextView) findViewById(R.id.tv_2);
    
            textViews.add(textView1);
            textViews.add(textView2);
    
            imgPublish.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.img_publish:
    
                    if (!isMenuOpen) {
                        showOpenAnim(80);
                        imgPublish.setImageResource(R.mipmap.publish_select);
                    }else {
                        showCloseAnim(80);
                        imgPublish.setImageResource(R.mipmap.fabu);
                    }
                    break;
            }
    
        }
    
        //打开扇形菜单的属性动画, dp为半径长度
        private void showOpenAnim(int dp) {
            textView1.setVisibility(View.VISIBLE);
            textView2.setVisibility(View.VISIBLE);
    
    
            //for循环来开始小图标的出现动画
            for (int i = 0; i < textViews.size(); i++) {
                AnimatorSet set = new AnimatorSet();
                //标题1与x轴负方向角度为20°,标题2为100°,转换为弧度
                double a = -Math.cos(20 * Math.PI / 180 * (i * 2 + 1));
                double b = -Math.sin(20 * Math.PI / 180 * (i * 2 + 1));
                double x = a * dip2px(dp);
                double y = b * dip2px(dp);
    
                set.playTogether(
                        ObjectAnimator.ofFloat(textViews.get(i), "translationX", (float) (x * 0.25), (float) x),
                        ObjectAnimator.ofFloat(textViews.get(i), "translationY", (float) (y * 0.25), (float) y)
                        , ObjectAnimator.ofFloat(textViews.get(i), "alpha", 0, 1).setDuration(2000)
                );
                set.setInterpolator(new BounceInterpolator());
                set.setDuration(500).setStartDelay(100);
                set.start();
    
                set.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {
    
                    }
    
                    @Override
                    public void onAnimationEnd(Animator animation) {
    
                        //菜单状态置打开
                        isMenuOpen = true;
                    }
    
                    @Override
                    public void onAnimationCancel(Animator animation) {
    
                    }
    
                    @Override
                    public void onAnimationRepeat(Animator animation) {
    
                    }
                });
            }
    
            //转动加号大图标本身45°
            ObjectAnimator rotate = ObjectAnimator.ofFloat(imgPublish, "rotation", 0, 90).setDuration(300);
            rotate.setInterpolator(new BounceInterpolator());
            rotate.start();
    
        }
    
        //关闭扇形菜单的属性动画,参数与打开时相反
        private void showCloseAnim(int dp) {
    
    
            //for循环来开始小图标的出现动画
            for (int i = 0; i < textViews.size(); i++) {
                AnimatorSet set = new AnimatorSet();
                double a = -Math.cos(20 * Math.PI / 180 * (i * 2 + 1));
                double b = -Math.sin(20 * Math.PI / 180 * (i * 2 + 1));
                double x = a * dip2px(dp);
                double y = b * dip2px(dp);
    
                set.playTogether(
                        ObjectAnimator.ofFloat(textViews.get(i), "translationX", (float) x, (float) (x * 0.25)),
                        ObjectAnimator.ofFloat(textViews.get(i), "translationY", (float) y, (float) (y * 0.25)),
                        ObjectAnimator.ofFloat(textViews.get(i), "alpha", 1, 0).setDuration(2000)
                );
    //            set.setInterpolator(new AccelerateInterpolator());
                set.setDuration(500);
                set.start();
    
                set.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {
    
                    }
    
                    @Override
                    public void onAnimationEnd(Animator animation) {
    
                        textView1.setVisibility(View.GONE);
                        textView2.setVisibility(View.GONE);
    
                        //菜单状态置关闭
                        isMenuOpen = false;
                    }
    
                    @Override
                    public void onAnimationCancel(Animator animation) {
    
                    }
    
                    @Override
                    public void onAnimationRepeat(Animator animation) {
    
                    }
                });
            }
    
    
            //转动加号大图标本身45°
            ObjectAnimator rotate = ObjectAnimator.ofFloat(imgPublish, "rotation", 0, 90).setDuration(300);
            rotate.setInterpolator(new BounceInterpolator());
            rotate.start();
    
    
        }
    
        private int dip2px(int value) {
            float density = getResources()
                    .getDisplayMetrics().density;
            return (int) (density * value + 0.5f);
        }
    
    }
    

    布局文件

    <?xml version="1.0" encoding="utf-8"?>
        <FrameLayout 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="com.example.lina.animationapplication.MainActivity">
    
    
        <TextView
            android:id="@+id/tv_1"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="bottom|end"
            android:layout_marginBottom="40dp"
            android:layout_marginRight="40dp"
            android:gravity="center"
            android:text="标题1"
            android:textColor="#ffffff"
            android:visibility="gone"
            android:background="@drawable/circle_purple"
            />
    
        <TextView
            android:id="@+id/tv_2"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="bottom|end"
            android:layout_marginBottom="40dp"
            android:layout_marginRight="40dp"
            android:gravity="center"
            android:text="标题2"
            android:textColor="#ffffff"
            android:visibility="gone"
            android:background="@drawable/circle_orange"/>
    
    
        <ImageView
                android:id="@+id/img_publish"
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:layout_gravity="bottom|end"
                android:layout_marginBottom="35dp"
                android:layout_marginRight="35dp"
                android:src="@mipmap/fabu"
                />
    
        </FrameLayout>
    

    circle_purple.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="oval">
    
        <solid android:color="#5d2a89" />
    
    </shape>
    

    参考
    Android开罐头———快速打造扇形卫星菜单

    相关文章

      网友评论

        本文标题:Android 带有弹出收缩动画的扇形菜单

        本文链接:https://www.haomeiwen.com/subject/jjdjcxtx.html