程序员人生 网站导航

android环形弹出菜单的实现

栏目:综合技术时间:2016-02-28 09:56:11

前言:

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


奉上效果图:

看到这里大家有无1种很熟习的感觉,对,99.99999999%你看过。空话不多说,开始今天的教程。

项目结构图:

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

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


这边有8个ImageView,位置是堆叠起来的(只要把主菜单,也就是那个红色的按钮的图片置于顶部就好了),这边我需要sorry的1点就是,图片的位置可能有点需要微调,处女座的自行略过。每一个ImageView都定义了1个id和1个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 ListimageViewList = 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() { //遍历第1个不是主菜单的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不了解的话,百度1下,有很多关于这个方面的资料,本文就不再赘述了。其实这边需要有1个小的数学技能,就是获得ImageView的角度问题,我这边是通过ImageView的个数出去除去主菜单的1个Imageview,将90度分为res.length⑵份,再乘以下标减去1,就是我们需要平移的角度。那末X的位移就是sina*R,y的唯1就是cosa*R,(这边的1.57是2分之圆周率)。行了,到这里就算是结束了。关闭效果就是把开启动画的进程逆过来就是了,这里不详细介绍。



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


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

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐