package com.loaderman.customviewdemo;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast; public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button mMenuButton;
private Button mItemButton1;
private Button mItemButton2;
private Button mItemButton3;
private Button mItemButton4;
private Button mItemButton5;
private boolean mIsMenuOpen = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initView();
} private void initView() {
mMenuButton = (Button) findViewById(R.id.menu);
mMenuButton.setOnClickListener(this); mItemButton1 = (Button) findViewById(R.id.item1);
mItemButton1.setOnClickListener(this); mItemButton2 = (Button) findViewById(R.id.item2);
mItemButton2.setOnClickListener(this); mItemButton3 = (Button) findViewById(R.id.item3);
mItemButton3.setOnClickListener(this); mItemButton4 = (Button) findViewById(R.id.item4);
mItemButton4.setOnClickListener(this); mItemButton5 = (Button) findViewById(R.id.item5);
mItemButton5.setOnClickListener(this);
} public void onClick(View v) {
if (!mIsMenuOpen) {
mIsMenuOpen = true;
openMenu();
} else {
Toast.makeText(this, "你点击了" + v, Toast.LENGTH_SHORT).show();
mIsMenuOpen = false;
closeMenu();
}
} private void openMenu() {
doAnimateOpen(mItemButton1, 0, 5, 300);
doAnimateOpen(mItemButton2, 1, 5, 300);
doAnimateOpen(mItemButton3, 2, 5, 300);
doAnimateOpen(mItemButton4, 3, 5, 300);
doAnimateOpen(mItemButton5, 4, 5, 300);
} private void closeMenu() {
doAnimateClose(mItemButton1, 0, 5, 300);
doAnimateClose(mItemButton2, 1, 5, 300);
doAnimateClose(mItemButton3, 2, 5, 300);
doAnimateClose(mItemButton4, 3, 5, 300);
doAnimateClose(mItemButton5, 4, 5, 300);
} /**
* 打开菜单的动画
*
* @param view 执行动画的view
* @param index view在动画序列中的顺序,从0开始
* @param total 动画序列的个数
* @param radius 动画半径
* <p/>
* Math.sin(x):x -- 为number类型的弧度,角度乘以0.017(2π/360)可以转变为弧度
*/
private void doAnimateOpen(View view, int index, int total, int radius) {
if (view.getVisibility() != View.VISIBLE) {
view.setVisibility(View.VISIBLE);
}
double degree = Math.toRadians(90) / (total - 1) * index;
int translationX = -(int) (radius * Math.sin(degree));
int translationY = -(int) (radius * Math.cos(degree));
AnimatorSet set = new AnimatorSet();
//包含平移、缩放和透明度动画
set.playTogether(
ObjectAnimator.ofFloat(view, "translationX", 0, translationX),
ObjectAnimator.ofFloat(view, "translationY", 0, translationY),
ObjectAnimator.ofFloat(view, "scaleX", 0f, 1f),
ObjectAnimator.ofFloat(view, "scaleY", 0f, 1f),
ObjectAnimator.ofFloat(view, "alpha", 0f, 1));
//动画周期为500ms
set.setDuration(500).start();
} /**
* 关闭菜单的动画
*
* @param view 执行动画的view
* @param index view在动画序列中的顺序
* @param total 动画序列的个数
* @param radius 动画半径
*/
private void doAnimateClose(final View view, int index, int total,
int radius) {
if (view.getVisibility() != View.VISIBLE) {
view.setVisibility(View.VISIBLE);
}
double degree = Math.PI * index / ((total - 1) * 2);
int translationX = -(int) (radius * Math.sin(degree));
int translationY = -(int) (radius * Math.cos(degree));
AnimatorSet set = new AnimatorSet();
//包含平移、缩放和透明度动画
set.playTogether(
ObjectAnimator.ofFloat(view, "translationX", translationX, 0),
ObjectAnimator.ofFloat(view, "translationY", translationY, 0),
ObjectAnimator.ofFloat(view, "scaleX", 1f, 0.1f),
ObjectAnimator.ofFloat(view, "scaleY", 1f, 0.1f),
ObjectAnimator.ofFloat(view, "alpha", 1f, 0f)); /**
* 解决方案二
*/
// set.addListener(new Animator.AnimatorListener() {
// public void onAnimationStart(Animator animation) {
//
// }
// public void onAnimationEnd(Animator animation) {
// view.setScaleX(1.0f);
// view.setScaleY(1.0f);
//
// }
//
// public void onAnimationCancel(Animator animation) {
//
// }
// public void onAnimationRepeat(Animator animation) {
//
// }
// });
set.setDuration(500).start();
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:layout_marginRight="10dp"> <Button
android:id="@+id/menu"
style="@style/MenuStyle"
android:background="@drawable/menu"/> <Button
android:id="@+id/item1"
style="@style/MenuItemStyle"
android:background="@drawable/circle1"
android:visibility="gone"/> <Button
android:id="@+id/item2"
style="@style/MenuItemStyle"
android:background="@drawable/circle2"
android:visibility="gone"/> <Button
android:id="@+id/item3"
style="@style/MenuItemStyle"
android:background="@drawable/circle3"
android:visibility="gone"/> <Button
android:id="@+id/item4"
style="@style/MenuItemStyle"
android:background="@drawable/circle4"
android:visibility="gone"/> <Button
android:id="@+id/item5"
style="@style/MenuItemStyle"
android:background="@drawable/circle5"
android:visibility="gone"/> </FrameLayout>
<resources>

    <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style> <style name="MenuStyle">
<item name="android:layout_width">50dp</item>
<item name="android:layout_height">50dp</item>
<item name="android:layout_gravity">right|bottom</item>
</style> <style name="MenuItemStyle">
<item name="android:layout_width">45dp</item>
<item name="android:layout_height">45dp</item>
<item name="android:layout_gravity">right|bottom</item>
</style> </resources>

效果:


package com.loaderman.customviewdemo;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends AppCompatActivity {
private Button mButton;
private TextView mTv1, mTv2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mButton = (Button) findViewById(R.id.btn);
mTv1 = (TextView) findViewById(R.id.tv_1);
mTv2 = (TextView) findViewById(R.id.tv_2); mButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
/**
* playSequentially 代表所有多动画依次播放
*/
// ObjectAnimator tv1BgAnimator = ObjectAnimator.ofInt(mTv1, "BackgroundColor", 0xffff00ff, 0xffffff00, 0xffff00ff);
// ObjectAnimator tv1TranslateY = ObjectAnimator.ofFloat(mTv1, "translationY", 0, 300, 0);
// ObjectAnimator tv2TranslateY = ObjectAnimator.ofFloat(mTv2, "translationY", 0, 400, 0);
//
// AnimatorSet animatorSet = new AnimatorSet();
// animatorSet.playSequentially(tv1BgAnimator, tv1TranslateY, tv2TranslateY);
// animatorSet.setDuration(1000);
// animatorSet.start(); /**
* playTogether 代表所有动画一起播放
*/
// ObjectAnimator tv1BgAnimator = ObjectAnimator.ofInt(mTv1, "BackgroundColor", 0xffff00ff, 0xffffff00, 0xffff00ff);
// ObjectAnimator tv1TranslateY = ObjectAnimator.ofFloat(mTv1, "translationY", 0, 400, 0);
// ObjectAnimator tv2TranslateY = ObjectAnimator.ofFloat(mTv2, "translationY", 0, 400, 0);
//
// AnimatorSet animatorSet = new AnimatorSet();
// animatorSet.playTogether(tv1BgAnimator, tv1TranslateY, tv2TranslateY);
// animatorSet.setDuration(1000);
// animatorSet.start(); /**
* 使用AnimatorSet.builder 可以自由组合动画,是playSequentially和playTogether的组合
*/
ObjectAnimator tv1BgAnimator = ObjectAnimator.ofInt(mTv1, "BackgroundColor", 0xffff00ff, 0xffffff00, 0xffff00ff);
ObjectAnimator tv1TranslateY = ObjectAnimator.ofFloat(mTv1, "translationY", 0, 400, 0);
ObjectAnimator tv2TranslateY = ObjectAnimator.ofFloat(mTv2, "translationY", 0, 400, 0); AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(tv1TranslateY).with(tv2TranslateY).after(tv1BgAnimator);
animatorSet.setDuration(2000);
animatorSet.start(); }
});
} }

动画监听:

  private AnimatorSet doListenerAnimation() {
ObjectAnimator tv1TranslateY = ObjectAnimator.ofFloat(mTv1, "translationY", 0, 400, 0);
ObjectAnimator tv2TranslateY = ObjectAnimator.ofFloat(mTv2, "translationY", 0, 400, 0);
tv2TranslateY.setRepeatCount(ValueAnimator.INFINITE); AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(tv1TranslateY).with(tv2TranslateY);
animatorSet.addListener(new Animator.AnimatorListener() {
public void onAnimationStart(Animator animation) {
Log.d(tag, "animator start");
} public void onAnimationEnd(Animator animation) {
Log.d(tag, "animator end");
} public void onAnimationCancel(Animator animation) {
Log.d(tag, "animator cancel");
} public void onAnimationRepeat(Animator animation) {
Log.d(tag, "animator repeat");
}
});
animatorSet.setDuration(2000);
animatorSet.start();
return animatorSet;
}

AnimatorSet学习示例代码的更多相关文章

  1. 一、从GitHub浏览Prism示例代码的方式入门WPF下的Prism

    最近这段时间一直在看一个开源软件PowerToys的源码,里面使用Modules的开发风格让我特别着迷,感觉比我现在写代码的风格好了太多太多.我尝试把PowerToys的架构分离了出来,但是发现代码维 ...

  2. 正则表达式学习笔记(附:Java版示例代码)

    具体学习推荐:正则表达式30分钟入门教程 .         除换行符以外的任意字符\w      word,正常字符,可以当做变量名的,字母.数字.下划线.汉字\s        space,空白符 ...

  3. Spring 注解学习 详细代码示例

    学习Sping注解,编写示例,最终整理成文章.如有错误,请指出. 该文章主要是针对新手的简单使用示例,讲述如何使用该注释,没有过多的原理解析. 已整理的注解请看右侧目录.写的示例代码也会在结尾附出. ...

  4. PyQt(Python+Qt)学习随笔:工具箱(QToolBox)编程使用的步骤及示例代码

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 使用toolBox开发应用时,通过Designer设计ui界面时,只能在Designer中设计too ...

  5. 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题

    调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...

  6. redis 学习笔记(2)-client端示例代码

    redis提供了几乎所有主流语言的client,java中主要使用二种:Jedis与Redisson 一.Jedis的使用 <dependency> <groupId>redi ...

  7. 【译】用Fragment创建动态的界面布局(附Android示例代码)

    原文链接:Building a Dynamic UI with Fragments 为了在Android上创建一个动态和多视图的用户界面,你需要封装UI控件和模块化Activity的行为,以便于你能够 ...

  8. C# 6新特性及示例代码

    今天推荐的其实是一个Github开源项目,不过这个开源项目是专门介绍C# 6的最新特性,并给出了示例代码. 我们知道,微软即将发布Windows 10和Visual Studio 2015,在VS20 ...

  9. Swift常用语法示例代码(二)

    此篇文章整理自我以前学习Swift时的一些练习代码,其存在的意义多是可以通过看示例代码更快地回忆Swift的主要语法. 如果你想系统学习Swift或者是Swift的初学者请绕路,感谢Github上Th ...

随机推荐

  1. Python绘制混淆矩阵,汉字显示label

    1. 在计算出混淆矩阵之后,想自己绘制图形(并且在图形上显示汉字),可用 #coding=utf-8 import matplotlib.pyplot as plt import numpy as n ...

  2. 说说客户端访问一个链接URL的全过程

    讲讲登录权限是如何控制的   我们可以把这个过程类比成一个电话对话的过程.当我们要打电话给某个人,首先要知道对方的电话号码,然后进行拨号.打通电话后我们会进行对话,当然要对话肯定需要共同的语言,如果一 ...

  3. Centos 6.x开机启动流程

    Centos 6.x开机启动流程 BIOS(COMS)检查 加载Bios,bios包含所有硬件信息(CPU,内存,硬盘,时钟,鼠标键盘等等) 读MBR 硬盘上第0磁道第一个扇区被称为MBR(maste ...

  4. SpringCloud之Eureka

    [前面的话]SpringCloud为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它配置简单,上手快,而且生态成 ...

  5. springboot的入门

    SpringBoot SpringBoot是SpringMVC的升级版,简化配置,很可能成为下一代的框架 1.新建项目 怎么创建springBoot项目呢? 创建步骤复杂一点点 New Project ...

  6. 1122 django中orm操作

    目录 1. 静态文件的配置 手动静态文件的访问资源 静态文件的动态绑定 2.request方法 2.1 请求方式 2.2 获取前端的请求方式 request.method 2.3 request方法 ...

  7. 《ABCD组》第四次作业:项目需求调研与分析

    <ABCD组>第四次作业:项目需求调研与分析 项目 内容 这个作业属于哪个课程 http://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https:// ...

  8. mac XXX 已损坏,打不开。 您应该将它移到废纸篓。

    mac 上的软件我改了某些配置,打开提示这个. 是因为安全认证问题. 在系统偏好设置里面,安全与隐私设置为允许任何来源就可以. 如果新版系统没有这个选项,那么在命令行输入:sudo spctl --m ...

  9. MyBatis和Spring整合案例

    1.所需要导入的jar文件 !--MyBatis和Spring的整合包 由MyBatis提供--> <dependency> <groupId>org.mybatis&l ...

  10. sql server 存储过程---游标的循环

    sqlserver中的循环遍历(普通循环和游标循环) sql 经常用到循环,下面介绍一下普通循环和游标循环 1.首先需要一个测试表数据Student