android环形弹出菜单的实现

前言:

最近在eoe上看到了一个环形菜单的效果,其实之前在github上早就见过了,看到实现代码也是挺多的,按照自己的思路做了一下效果,实现还是比较简单的。这个项目离组件还是有一定的上升空间的,只要是教会大家如何去做一个类似的效果。


奉上效果图:

android环形弹出菜单的实现_第1张图片

看到这里大家有没有一种很熟悉的感觉,对,99.99999999%你看过。废话不多说,开始今天的教程。

项目结构图:

android环形弹出菜单的实现_第2张图片

对,你没有看错,就只有这两个文件需要修改,其他都是默认生成的文件。

我们先来看看activity_main.xml中的布局:



    

    

    

    

    

    

    

    


这边有8个ImageView,位置是重叠起来的(只要把主菜单,也就是那个红色的按钮的图片置于顶部就行了),这边我需要sorry的一点就是,图片的位置可能有点需要微调,处女座的自行略过。每个ImageView都定义了一个id和一个onClick事件。基本都是我们之前都熟悉的东西,没有什么需要特别介绍的。


主要代码来了,前方高能。

MainActivity.java的主要代码:

package com.beyole.objectanimatortest;

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

import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.BounceInterpolator;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {

	//图片资源
	private int[] res = { R.id.id_a, R.id.id_b, R.id.id_c, R.id.id_d, R.id.id_e, R.id.id_f, R.id.id_g, R.id.id_h };
	//存放ImageView
	private List imageViewList = new ArrayList();
	//菜单是不是展开
	private boolean isNotExpand = true;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//利用循环,初始化ImageView组件
		for (int i = 0; i < res.length; i++) {
			ImageView imageView = (ImageView) findViewById(res[i]);
			//存放在list中
			imageViewList.add(imageView);
		}
	}

	//点击事件
	public void clickview(View view) {
		switch (view.getId()) {
		//主菜单被点击
		case R.id.id_a:
			//主菜单没有展开时被点击
			if (isNotExpand == true) {
				//启动动画
				startAnim();
			} else {
				//关闭动画
				closeAnim();
			}
			break;
			//定义其他组件被点击时触发的事件
		default:
			Toast.makeText(MainActivity.this, "您点击了:" + view.getId(), Toast.LENGTH_LONG).show();
			break;
		}
	}

	//关闭动画
	private void closeAnim() {
		for (int i = 1; i < res.length; i++) {
			float angle = (90 * 1.0f / (res.length - 2)) * (i - 1);
			PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("translationX", (float) (Math.sin((angle * 1.57 / 90)) * 200), 0);
			PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("translationY", (float) (Math.cos((angle * 1.57 / 90)) * 200), 0);
			ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageViewList.get(i), holder1, holder2);
			// ObjectAnimator animator =
			// ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", i * 60,
			// 0);
			animator.setDuration(300);
			animator.start();
			isNotExpand = true;

		}
	}

	//开始动画
	private void startAnim() {
		//遍历第一个不是主菜单的ImageView列表
		for (int i = 1; i < res.length; i++) {
			//获取展开角度
			float angle = (90 * 1.0f / (res.length - 2)) * (i - 1);
			//获取X位移
			PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("translationX", 0, (float) (Math.sin((angle * 1.57 / 90)) * 200));
			//获取Y位移
			PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("translationY", 0, (float) (Math.cos((angle * 1.57 / 90)) * 200));
			//设置ImageView的属性动画
			ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageViewList.get(i), holder1, holder2);
			// ObjectAnimator animator =
			// ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", 0, i *
			// 60);
			//动画时间
			animator.setDuration(1000);
			//动画延迟时间
			animator.setFrameDelay(500 * i);
			//设置加速器
			animator.setInterpolator(new BounceInterpolator());
			//启动动画
			animator.start();
			isNotExpand = false;
		}
	}
}
本篇的效果主要是依靠ObjectAnimator属性动画来实现的,如果对ObjectAnimator不了解的话,百度一下,有很多关于这个方面的资料,本文就不再赘述了。其实这边需要有一个小的数学技巧,就是获取ImageView的角度问题,我这边是通过ImageView的个数出去除去主菜单的一个Imageview,将90度分为res.length-2份,再乘以下标减去1,就是我们需要平移的角度。那么X的位移就是sina*R,y的唯一就是cosa*R,(这边的1.57是二分之圆周率)。行了,到这里就算是结束了。关闭效果就是把开启动画的过程逆过来就是了,这里不详细介绍。



可能有讲的不好的地方,或者有需要改进的代码,欢迎大家提出宝贵意见,我会好好改进的。


csdn下载地址:http://download.csdn.net/detail/xuejiawei123/9197525

github地址:https://github.com/xuejiawei/beyole_android_ObjectAnimatorToolBars

你可能感兴趣的:(安卓)