好久没更新了,今天来写写东西,实现一个圆形的按钮组控件,那么听名字,我们就能能感觉到实现的是自定义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);
}