自定义View实现圆形按钮组

好久没更新了,今天来写写东西,实现一个圆形的按钮组控件,那么听名字,我们就能能感觉到实现的是自定义ViewGroup,对的,一起先来看看效果
这里写图片描述

感觉还是挺简单的,的确很简单,那就学习一下,

实现上面的效果分为一下几步
1.重写onMeasure()对子VIew进行测量
2.在onLayout里面设置子view的布局
3.在设置点击事件,实现点击效果

就上面三步,就Ok
开搞

public class MyCircleView extends ViewGroup implements View.OnClickListener {

    float radius = 100f;//半径
    private int height;
    private int width;
    private String TAG = "test";
    private boolean open = false;

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

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

    public MyCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        radius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, radius, getResources().getDisplayMetrics());
    }

上面就是定义了一些参数,以及实现构造,在第三个构造中,我对radius进行了转化

   @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        measureChildren(widthMeasureSpec, heightMeasureSpec);
    }

这里就是对子view进行测量,这个还是比较重要的,不然view.getMeasureHeight没值,这个可以参看源码

之后我们需要对子VIew设置布局


    @Override
    protected void onLayout(boolean c, int l, int t, int r, int b) {
        View view1 = getChildAt(0);
        view1.setOnClickListener(this);
        centerButton(view1);
        for (int i = 1; i < getChildCount(); i++) {
            View view = getChildAt(i);
            view.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    scaleAnimation(view);
                }
            });
            int left = (int) (width / 2 - Math.cos(Math.toRadians((i - 1) * 45)) * radius - view.getMeasuredWidth() / 2);
            int top = (int) (height - Math.sin(Math.toRadians((i - 1) * 45)) * radius - view.getMeasuredHeight());
            view.layout(left, top, left + view.getMeasuredHeight(), top + view.getMeasuredHeight());
        }
    }

    private void scaleAnimation(View view) {
        AnimatorSet animatorSet = new AnimatorSet();
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "scaleX", 0, 2, 1);
        ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(view, "scaleY", 0, 2, 1);
        ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(view, "alpha", 1, 0, 1);
        animatorSet.playTogether(objectAnimator, objectAnimator1, objectAnimator3);
        animatorSet.start();

    }

上面的代码就是对子view进行了sin和cos的运算,计算其对应的坐标,这个就不算了,实在看不懂可以call我,然后就是对子view设置了动画

设置好坐标之后,我们就要开始设置点击事件的动画

  @Override
    public void onClick(View view) {
//这里是对中间的按钮设置的点击事件的处理,
//这里的标志位代表的是展开还是合上,
        if (!open) {
            centerButtonRotateAnimation(view);
            subButtonAnimation();
            open = true;
        } else {
            centerButtonRotateAnimation(view);
            subButonCloseAnimation();
            open = false;
        }
    }

下面是实现动画的方法

private void centerButton(View view) {
        height = getMeasuredHeight();
        width = getMeasuredWidth();
        int subViewWidth = view.getMeasuredWidth();
        int subViewHeight = view.getMeasuredHeight();
        view.layout((width - subViewWidth) / 2, height - subViewHeight, (width + subViewWidth) / 2, height);
    }

    /**
     * 其他子按钮的平移加旋转加透明度动画设置
     */
    private void subButtonAnimation() {
        for (int i = 1; i < getChildCount(); i++) {
            View view = getChildAt(i);
            createAnimationSet(view);
        }
    }

    private void subButonCloseAnimation() {

        for (int i = 1; i < getChildCount(); i++) {
            View view = getChildAt(i);
            closeAnimationSet(view);
        }
    }

    public void createAnimationSet(View view) {

        view.setClickable(false);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(1000);
        animatorSet.setInterpolator(new BounceInterpolator());

        //移动动画
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "translationX", 0, width / 2 - view.getLeft() - view.getMeasuredWidth() / 2);
        ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(view, "translationY", 0, height - view.getTop() - view.getMeasuredHeight());

        //旋转动画

        ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(view, "rotation", 0, 360);

        //透明度动画
        ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(view, "alpha", 1, 0);

        animatorSet.playTogether(objectAnimator, objectAnimator1, objectAnimator2, objectAnimator3);
        animatorSet.start();


    }


    public void closeAnimationSet(View view) {

        view.setClickable(true);
//这里设置view不能点击,是因为我们在闭合子view时,会造成控件的相叠,那么会使得中间的button的点击事件出现问题,通过这个设置可以解决这个问题
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(1000);
        animatorSet.setInterpolator(new BounceInterpolator());

        //移动动画
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "translationX", width / 2 - view.getLeft() - view.getMeasuredWidth() / 2, 0);
        ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(view, "translationY", height - view.getTop() - view.getMeasuredHeight(), 0);

        //旋转动画

        ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(view, "rotation", 360, 0);

        //透明度动画
        ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(view, "alpha", 0, 1);

        animatorSet.playTogether(objectAnimator, objectAnimator1, objectAnimator2, objectAnimator3);
        animatorSet.start();


    }


    /**
     * 中间按钮点击的动画
     */
    private void centerButtonRotateAnimation(View view) {

        RotateAnimation rotateAnimation = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5F, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnimation.setDuration(1000);
        rotateAnimation.setFillAfter(true);
        view.startAnimation(rotateAnimation);
    }

猜你喜欢

转载自blog.csdn.net/qq_37657081/article/details/80849589