├── .gitignore
├── README-CN.md
├── README.md
├── build.gradle
├── example
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── github
│ │ └── hujiaweibujidao
│ │ └── example
│ │ ├── ApplicationTest.java
│ │ └── MainActivityTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── ic_launcher-web.png
│ ├── java
│ │ └── com
│ │ │ └── github
│ │ │ └── hujiaweibujidao
│ │ │ └── example
│ │ │ ├── activity
│ │ │ ├── Bounce2Activity.java
│ │ │ ├── BounceActivity.java
│ │ │ ├── CustomActivity.java
│ │ │ ├── Demo2Activity.java
│ │ │ ├── DemoActivity.java
│ │ │ ├── EvaluatorActivity.java
│ │ │ ├── InterpolatorActivity.java
│ │ │ └── MainActivity.java
│ │ │ ├── adapter
│ │ │ ├── EvaluatorAdapter.java
│ │ │ └── InterpolatorAdapter.java
│ │ │ └── view
│ │ │ ├── CursorView.java
│ │ │ ├── EvaluatorView.java
│ │ │ └── InterpolatorView.java
│ └── res
│ │ ├── drawable
│ │ └── circle.xml
│ │ ├── layout
│ │ ├── activity_demo.xml
│ │ ├── activity_evaluator.xml
│ │ ├── activity_interpolator.xml
│ │ ├── activity_main.xml
│ │ ├── adapter.xml
│ │ └── item.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── github
│ └── hujiaweibujidao
│ └── example
│ └── ExampleUnitTest.java
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── library
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── github
│ │ └── hujiaweibujidao
│ │ └── yava
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── github
│ │ │ └── hujiaweibujidao
│ │ │ └── yava
│ │ │ ├── AbstractFunction.java
│ │ │ ├── EasingFunction.java
│ │ │ ├── Functions.java
│ │ │ └── IFunction.java
│ └── res
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── github
│ └── hujiaweibujidao
│ └── yava
│ └── ExampleUnitTest.java
├── settings.gradle
└── yava.gif
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/README-CN.md:
--------------------------------------------------------------------------------
1 | [](https://www.jitpack.io/#hujiaweibujidao/yava) [](http://android-arsenal.com/details/1/3639)
2 |
3 | ## Yava
4 |
5 | > Yet Another View Animation ( a simple and elegant view animation helper library for Android)
6 |
7 | This library helps you convert any curve into ready-to-use `Interpolator` or `TypeEvaluator` for `ValueAnimator`, and thirty Rovert Penner's Easing Functions are already included.
8 |
9 | 关于本项目的创建缘由以及实现思路,欢迎阅读我写的这三篇文章,详细介绍了Android动画中的三个重要类:`ValueAnimator`、`TypeEvaluator`和`TimeInterpolator`,我保证您会有所收获的 😜
10 |
11 | [当数学遇上动画:讲述`ValueAnimator`、`TypeEvaluator`和`TimeInterpolator`之间的恩恩怨怨(1)](http://hujiaweibujidao.github.io/blog/2016/05/26/when-math-meets-android-animation/)
12 | [当数学遇上动画:讲述`ValueAnimator`、`TypeEvaluator`和`TimeInterpolator`之间的恩恩怨怨(2)](http://hujiaweibujidao.github.io/blog/2016/05/27/When-Math-meets-Android-Animation-2/)
13 | [当数学遇上动画:讲述`ValueAnimator`、`TypeEvaluator`和`TimeInterpolator`之间的恩恩怨怨(3)](http://hujiaweibujidao.github.io/blog/2016/05/27/When-Math-meets-Android-Animation-3/)
14 |
15 | 该项目实现的功能就是将抽象的函数曲线轻松转换成立即可用的`Interpolator`和`TypeEvaluator`,然后应用在Android动画中。这个项目还提供了常见的30个缓动函数(Easing Functions)的实现,它们既可以当做`Interpolator`来用,又可以当做`TypeEvaluator`来用,真的非常方便。
16 |
17 | ## Screenshot
18 |
19 | 
20 |
21 | ## Usage
22 |
23 | 举个例子,以弹跳动画效果为例,可以直接使用`EasingFunction.BOUNCE_OUT`作为`Interpolator`或者`TypeEvaluator`来使用:
24 |
25 | 第一种方式:使用线性插值器和自定义的TypeEvaluator
26 |
27 | ```java
28 | ObjectAnimator animator1 = new ObjectAnimator();
29 | animator1.setTarget(textView1);
30 | animator1.setPropertyName("translationY");
31 | animator1.setFloatValues(0f, -100f);
32 | animator1.setDuration(1000);
33 | animator1.setInterpolator(new LinearInterpolator());
34 | animator1.setEvaluator(EasingFunction.BOUNCE_OUT); //这里将EasingFunction.BOUNCE_OUT作为TypeEvaluator来使用
35 | animator1.start();
36 | ```
37 |
38 | 第二种方式:使用自定义的Interpolator和"线性估值器"
39 |
40 | ```java
41 | ObjectAnimator animator2 = new ObjectAnimator();
42 | animator2.setTarget(textView2);
43 | animator2.setPropertyName("translationY");
44 | animator2.setFloatValues(0f, -100f);
45 | animator2.setDuration(1000);
46 | animator2.setInterpolator(EasingFunction.BOUNCE_OUT); //这里将EasingFunction.BOUNCE_OUT作为Interpolator来使用
47 | animator2.setEvaluator(new FloatEvaluator());
48 | animator2.start();
49 | ```
50 |
51 | 如果你想使用自己定义的函数来制作动画,可以使用`Functions`的`with`方法,传入一个实现了`IFunction`接口的类就行,返回值你既可以当做`Interpolator`,也可以当做`TypeEvaluator`来使用
52 |
53 | 代码示例:
54 |
55 | ```java
56 | ObjectAnimator animator1 = new ObjectAnimator();
57 | animator1.setTarget(textView1);
58 | animator1.setPropertyName("translationY");
59 | animator1.setFloatValues(0f, -100f);
60 | animator1.setDuration(1000);
61 | animator1.setInterpolator(new LinearInterpolator());
62 | animator1.setEvaluator(Functions.with(new IFunction() { //自定义为TypeEvaluator
63 | @Override
64 | public float getValue(float input) {
65 | return input * 2 + 3;
66 | }
67 | }));
68 | animator1.start();
69 | ```
70 |
71 | 或者这样:
72 |
73 |
74 | ```java
75 | ObjectAnimator animator2 = new ObjectAnimator();
76 | animator2.setTarget(textView2);
77 | animator2.setPropertyName("translationY");
78 | animator2.setFloatValues(0f, -100f);
79 | animator2.setDuration(1000);
80 | animator2.setInterpolator(Functions.with(new IFunction() { //自定义为Interpolator
81 | @Override
82 | public float getValue(float input) {
83 | return input * 2 + 3;
84 | }
85 | }));
86 | animator2.setEvaluator(new FloatEvaluator());
87 | animator2.start();
88 | ```
89 |
90 | ## Setup
91 |
92 | 你只需要拷贝`library`中的4个重要类到你的项目中就行了!
93 |
94 | 或者
95 |
96 | 1.在项目根目录的`build.gradle`文件中加入
97 |
98 | ```
99 | allprojects {
100 | repositories {
101 | ...
102 | maven { url "https://www.jitpack.io" }
103 | }
104 | }
105 | ```
106 |
107 | 2.然后在需要的`build.gradle`文件中加入依赖
108 |
109 | ```
110 | dependencies {
111 | compile 'com.github.hujiaweibujidao:yava:1.0.0'
112 | }
113 | ```
114 |
115 | ## Documentation
116 |
117 | 项目只有4个核心类,放在`library`中
118 |
119 | (1) `IFunction`接口
120 |
121 | ```java
122 | /**
123 | * 函数接口:给定输入,得到输出
124 | */
125 | public interface IFunction {
126 | float getValue(float input);
127 | }
128 | ```
129 |
130 | (2)`AbstractFunction`抽象类
131 |
132 | ```java
133 | /**
134 | * 抽象函数实现,既可以当做简单函数使用,也可以当做Interpolator或者TypeEvaluator去用于制作动画
135 | */
136 | public abstract class AbstractFunction implements IFunction, Interpolator, TypeEvaluator {
137 |
138 | @Override
139 | public float getInterpolation(float input) {
140 | return getValue(input);
141 | }
142 |
143 | @Override
144 | public Float evaluate(float fraction, Float startValue, Float endValue) {
145 | return startValue + getValue(fraction) * (endValue - startValue);
146 | }
147 | }
148 | ```
149 |
150 | (3)`Functions`类
151 |
152 | ```java
153 | /**
154 | * 工具类,将自定义的函数快速封装成AbstractFunction
155 | */
156 | class Functions {
157 |
158 | public static AbstractFunction with(final IFunction function) {
159 | return new AbstractFunction() {
160 | @Override
161 | public float getValue(float input) {
162 | return function.getValue(input);
163 | }
164 | };
165 | }
166 | }
167 | ```
168 |
169 | (4)`EasingFunction`枚举:包含了30个常见的缓动函数
170 |
171 | ```java
172 | /**
173 | * 常见的30个缓动函数的实现
174 | */
175 | public enum EasingFunction implements IFunction, Interpolator, TypeEvaluator {
176 |
177 | /* ------------------------------------------------------------------------------------------- */
178 | /* BACK
179 | /* ------------------------------------------------------------------------------------------- */
180 | BACK_IN {
181 | @Override
182 | public float getValue(float input) {
183 | return input * input * ((1.70158f + 1) * input - 1.70158f);
184 | }
185 | },
186 | BACK_OUT {
187 | @Override
188 | public float getValue(float input) {
189 | return ((input = input - 1) * input * ((1.70158f + 1) * input + 1.70158f) + 1);
190 | }
191 | },
192 | BACK_INOUT {
193 | @Override
194 | public float getValue(float input) {
195 | float s = 1.70158f;
196 | if ((input *= 2) < 1) {
197 | return 0.5f * (input * input * (((s *= (1.525f)) + 1) * input - s));
198 | }
199 | return 0.5f * ((input -= 2) * input * (((s *= (1.525f)) + 1) * input + s) + 2);
200 | }
201 | },
202 |
203 | //other easing functions ......
204 |
205 | //如果这个function在求值的时候需要duration作为参数的话,那么可以通过setDuration来设置,否则使用默认值
206 | private float duration = 1000f;
207 |
208 | public float getDuration() {
209 | return duration;
210 | }
211 |
212 | public EasingFunction setDuration(float duration) {
213 | this.duration = duration;
214 | return this;
215 | }
216 |
217 | //将Function当做Interpolator使用,默认的实现,不需要枚举元素去重新实现
218 | @Override
219 | public float getInterpolation(float input) {
220 | return getValue(input);
221 | }
222 |
223 | //将Function当做TypeEvaluator使用,默认的实现,不需要枚举元素去重新实现
224 | @Override
225 | public Float evaluate(float fraction, Float startValue, Float endValue) {
226 | return startValue + getValue(fraction) * (endValue - startValue);
227 | }
228 |
229 | //几个数学常量
230 | public static final float PI = (float) Math.PI;
231 | public static float TWO_PI = PI * 2.0f;
232 | public static float HALF_PI = PI * 0.5f;
233 | }
234 | ```
235 |
236 | ## Reference
237 |
238 | 本项目主要参考了以下项目和内容
239 | 1.[EaseInterpolator](https://github.com/cimi-chen/EaseInterpolator)
240 | 2.[AnimationEasingFunctions](https://github.com/daimajia/AnimationEasingFunctions)
241 | 3.[easings.net](http://easings.net/)
242 |
243 | ## License
244 |
245 | ```
246 | The MIT License (MIT)
247 |
248 | Copyright (c) 2016 Hujiawei
249 |
250 | Permission is hereby granted, free of charge, to any person obtaining a copy
251 | of this software and associated documentation files (the "Software"), to deal
252 | in the Software without restriction, including without limitation the rights
253 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
254 | copies of the Software, and to permit persons to whom the Software is
255 | furnished to do so, subject to the following conditions:
256 |
257 | The above copyright notice and this permission notice shall be included in all
258 | copies or substantial portions of the Software.
259 |
260 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
261 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
262 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
263 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
264 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
265 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
266 | SOFTWARE.
267 | ```
268 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [中文说明](README-CN.md) [](https://www.jitpack.io/#hujiaweibujidao/yava) [](http://android-arsenal.com/details/1/3639)
2 |
3 | ## Yava
4 |
5 | > Yet Another View Animation ( a simple and elegant view animation helper library for Android)
6 |
7 | This library helps you convert any curve into ready-to-use `Interpolator` or `TypeEvaluator` for `ValueAnimator`, and thirty Rovert Penner's Easing Functions are already included.
8 |
9 | You may read the following three articles to know about the reason why I create this project, and how to implement it. They fully described the relations among `ValueAnimator`、`TypeEvaluator` and `TimeInterpolator`, hope it helps.
10 |
11 | [When Math Meets Animation(1)](https://javayhu.github.io/blog/2016-05-26-when-math-meets-android-animation-1)
12 | [When Math Meets Animation(2)](https://javayhu.github.io/blog/2016-05-27-When-Math-meets-Android-Animation-2)
13 | [When Math Meets Animation(3)](https://javayhu.github.io/blog/2016-05-28-When-Math-meets-Android-Animation-3)
14 |
15 | ## Screenshot
16 |
17 | 
18 |
19 | ## Usage
20 |
21 | For example, if you want to create a `BOUNCE_OUT` animation, you can directly use `EasingFunction.BOUNCE_OUT` as `Interpolator` or `TypeEvaluator` for your `ValueAnimator`.
22 |
23 | Option 1: use `LinearInterpolator` with `EasingFunction.BOUNCE_OUT` (as `TypeEvaluator`)
24 |
25 | ```java
26 | ObjectAnimator animator1 = new ObjectAnimator();
27 | animator1.setTarget(textView1);
28 | animator1.setPropertyName("translationY");
29 | animator1.setFloatValues(0f, -100f);
30 | animator1.setDuration(1000);
31 |
32 | animator1.setInterpolator(new LinearInterpolator());
33 | animator1.setEvaluator(EasingFunction.BOUNCE_OUT); //use `EasingFunction.BOUNCE_OUT` as `TypeEvaluator`
34 |
35 | animator1.start();
36 | ```
37 |
38 | Option 2: use `EasingFunction.BOUNCE_OUT` (as `Interpolator`) with `FloatEvaluator` (`"Linear TypeEvaluator"`)
39 |
40 | ```java
41 | ObjectAnimator animator2 = new ObjectAnimator();
42 | animator2.setTarget(textView2);
43 | animator2.setPropertyName("translationY");
44 | animator2.setFloatValues(0f, -100f);
45 | animator2.setDuration(1000);
46 |
47 | animator2.setInterpolator(EasingFunction.BOUNCE_OUT); //use `EasingFunction.BOUNCE_OUT` as `Interpolator`
48 | animator2.setEvaluator(new FloatEvaluator());
49 |
50 | animator2.start();
51 | ```
52 |
53 | Want to use your customized function curve? It's simple!
54 | Try `Functions.with(IFunction youFunctionImplementation)`!
55 |
56 | Example 1: use it as `TypeEvaluator`
57 |
58 | ```java
59 | ObjectAnimator animator1 = new ObjectAnimator();
60 | animator1.setTarget(textView1);
61 | animator1.setPropertyName("translationY");
62 | animator1.setFloatValues(0f, -100f);
63 | animator1.setDuration(1000);
64 |
65 | animator1.setInterpolator(new LinearInterpolator());
66 | animator1.setEvaluator(Functions.with(new IFunction() { //customized TypeEvaluator
67 | @Override
68 | public float getValue(float input) {
69 | return input * 2 + 3;
70 | }
71 | }));
72 |
73 | animator1.start();
74 | ```
75 |
76 | Or you can also use it as `Interpolator`:
77 |
78 | ```java
79 | ObjectAnimator animator2 = new ObjectAnimator();
80 | animator2.setTarget(textView2);
81 | animator2.setPropertyName("translationY");
82 | animator2.setFloatValues(0f, -100f);
83 | animator2.setDuration(1000);
84 |
85 | animator2.setInterpolator(Functions.with(new IFunction() { //customized Interpolator
86 | @Override
87 | public float getValue(float input) {
88 | return input * 2 + 3;
89 | }
90 | }));
91 | animator2.setEvaluator(new FloatEvaluator());
92 |
93 | animator2.start();
94 | ```
95 |
96 | ## Setup
97 |
98 | Copy those four classes into your project, then you are set!
99 |
100 | OR
101 |
102 | 1.add this in your `build.gradle` file in root project
103 |
104 | ```
105 | allprojects {
106 | repositories {
107 | ...
108 | maven { url "https://www.jitpack.io" }
109 | }
110 | }
111 | ```
112 |
113 | 2.add the following dependency
114 |
115 | ```
116 | dependencies {
117 | compile 'com.github.hujiaweibujidao:yava:1.0.0'
118 | }
119 | ```
120 |
121 | ## Documentation
122 |
123 | There are only four core classes in `library`.
124 |
125 | (1) `IFunction`: interface
126 |
127 | ```java
128 | /**
129 | * Function Interface: given input, get the value result
130 | */
131 | public interface IFunction {
132 | float getValue(float input);
133 | }
134 | ```
135 |
136 | (2)`AbstractFunction`: abstract class
137 |
138 | ```java
139 | /**
140 | * abstract function, you can use it as `Interpolator` or `TypeEvaluator`
141 | */
142 | public abstract class AbstractFunction implements IFunction, Interpolator, TypeEvaluator {
143 |
144 | @Override
145 | public float getInterpolation(float input) {
146 | return getValue(input);
147 | }
148 |
149 | @Override
150 | public Float evaluate(float fraction, Float startValue, Float endValue) {
151 | return startValue + getValue(fraction) * (endValue - startValue);
152 | }
153 | }
154 | ```
155 |
156 | (3)`Functions`: class
157 |
158 | ```java
159 | /**
160 | * convert any function curve to ready-to-use AbstractFunction
161 | */
162 | class Functions {
163 |
164 | public static AbstractFunction with(final IFunction function) {
165 | return new AbstractFunction() {
166 | @Override
167 | public float getValue(float input) {
168 | return function.getValue(input);
169 | }
170 | };
171 | }
172 | }
173 | ```
174 |
175 | (4)`EasingFunction`: enum with thirty Rovert Penner's Easing Functions included
176 |
177 | ```java
178 | /**
179 | * thirty Rovert Penner's Easing Functions
180 | */
181 | public enum EasingFunction implements IFunction, Interpolator, TypeEvaluator {
182 |
183 | /* ------------------------------------------------------------------------------------------- */
184 | /* BACK
185 | /* ------------------------------------------------------------------------------------------- */
186 | BACK_IN {
187 | @Override
188 | public float getValue(float input) {
189 | return input * input * ((1.70158f + 1) * input - 1.70158f);
190 | }
191 | },
192 | BACK_OUT {
193 | @Override
194 | public float getValue(float input) {
195 | return ((input = input - 1) * input * ((1.70158f + 1) * input + 1.70158f) + 1);
196 | }
197 | },
198 | BACK_INOUT {
199 | @Override
200 | public float getValue(float input) {
201 | float s = 1.70158f;
202 | if ((input *= 2) < 1) {
203 | return 0.5f * (input * input * (((s *= (1.525f)) + 1) * input - s));
204 | }
205 | return 0.5f * ((input -= 2) * input * (((s *= (1.525f)) + 1) * input + s) + 2);
206 | }
207 | },
208 |
209 | //other easing functions ......
210 |
211 | private float duration = 1000f;
212 |
213 | public float getDuration() {
214 | return duration;
215 | }
216 |
217 | public EasingFunction setDuration(float duration) {
218 | this.duration = duration;
219 | return this;
220 | }
221 |
222 | @Override
223 | public float getInterpolation(float input) {
224 | return getValue(input);
225 | }
226 |
227 | @Override
228 | public Float evaluate(float fraction, Float startValue, Float endValue) {
229 | return startValue + getValue(fraction) * (endValue - startValue);
230 | }
231 |
232 | //Math constants
233 | public static final float PI = (float) Math.PI;
234 | public static float TWO_PI = PI * 2.0f;
235 | public static float HALF_PI = PI * 0.5f;
236 | }
237 | ```
238 |
239 | ## References
240 |
241 | 1.[EaseInterpolator](https://github.com/cimi-chen/EaseInterpolator)
242 | 2.[AnimationEasingFunctions](https://github.com/daimajia/AnimationEasingFunctions)
243 | 3.[easings.net](http://easings.net/)
244 |
245 | ### [wava](https://github.com/hujiaweibujidao/wava)
246 |
247 | Currently I'm planning to build another fancy animation library named [`wava`](https://github.com/hujiaweibujidao/wava) for Android, follow that project or my Github if you have any interest in it. 😄
248 |
249 | ## License
250 |
251 | ```
252 | The MIT License (MIT)
253 |
254 | Copyright (c) 2016 Hujiawei
255 |
256 | Permission is hereby granted, free of charge, to any person obtaining a copy
257 | of this software and associated documentation files (the "Software"), to deal
258 | in the Software without restriction, including without limitation the rights
259 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
260 | copies of the Software, and to permit persons to whom the Software is
261 | furnished to do so, subject to the following conditions:
262 |
263 | The above copyright notice and this permission notice shall be included in all
264 | copies or substantial portions of the Software.
265 |
266 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
267 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
268 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
269 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
270 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
271 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
272 | SOFTWARE.
273 | ```
274 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.1.0'
9 |
10 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | jcenter()
19 | }
20 | }
21 |
22 | task clean(type: Delete) {
23 | delete rootProject.buildDir
24 | }
25 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/example/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.3"
6 |
7 | defaultConfig {
8 | applicationId "com.github.hujiaweibujidao.yava"
9 | minSdkVersion 16
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | testCompile 'junit:junit:4.12'
25 | compile 'com.android.support:appcompat-v7:23.4.0'
26 | compile project(':library')
27 | }
28 |
--------------------------------------------------------------------------------
/example/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/hujiawei/Android/android_sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/example/src/androidTest/java/com/github/hujiaweibujidao/example/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/example/src/androidTest/java/com/github/hujiaweibujidao/example/MainActivityTest.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example;
2 |
3 | import android.test.AndroidTestCase;
4 | import android.util.Log;
5 | import android.widget.Toast;
6 |
7 | /**
8 | * @author hujiawei 16/5/25
9 | */
10 | public class MainActivityTest extends AndroidTestCase {
11 |
12 | public void setUp() throws Exception {
13 |
14 | }
15 |
16 | public void tearDown() throws Exception {
17 |
18 | }
19 |
20 | public void testOnCreate() throws Exception {
21 | Log.d("test","ok");
22 | Toast.makeText(getContext(), "test ok", Toast.LENGTH_SHORT).show();
23 | }
24 | }
--------------------------------------------------------------------------------
/example/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/example/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/javayhu/yava/ca558f24c15b584eb463054620ea3efc85700e91/example/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/example/src/main/java/com/github/hujiaweibujidao/example/activity/Bounce2Activity.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example.activity;
2 |
3 | import android.animation.FloatEvaluator;
4 | import android.animation.ObjectAnimator;
5 | import android.os.Bundle;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.view.View;
8 | import android.view.animation.LinearInterpolator;
9 | import android.widget.Button;
10 | import android.widget.TextView;
11 |
12 | import com.github.hujiaweibujidao.yava.EasingFunction;
13 | import com.github.hujiaweibujidao.example.R;
14 |
15 | /**
16 | * 演示LinearInterpolator和TypeEvaluator 与 TimeInterpolator和LinearEvaluator 的动画效果一样
17 | * 这里使用ObjectAnimator来验证,弹跳效果
18 | */
19 | public class Bounce2Activity extends AppCompatActivity {
20 |
21 | TextView textView1;
22 | TextView textView2;
23 | Button buttonStart;
24 | Button buttonStart2;
25 | Button buttonStartAll;
26 |
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_demo);
31 |
32 | textView1 = (TextView) findViewById(R.id.textview1);
33 | textView2 = (TextView) findViewById(R.id.textview2);
34 | buttonStart = (Button) findViewById(R.id.buttonStart1);
35 | buttonStart2 = (Button) findViewById(R.id.buttonStart2);
36 | buttonStartAll = (Button) findViewById(R.id.buttonStartAll);
37 |
38 | buttonStart.setOnClickListener(new View.OnClickListener() {
39 | @Override
40 | public void onClick(View v) {
41 | startAnimator1();
42 | }
43 | });
44 | buttonStart2.setOnClickListener(new View.OnClickListener() {
45 | @Override
46 | public void onClick(View v) {
47 | startAnimator2();
48 | }
49 | });
50 | buttonStartAll.setOnClickListener(new View.OnClickListener() {
51 | @Override
52 | public void onClick(View v) {
53 | startAnimator1();
54 | startAnimator2();
55 | }
56 | });
57 | }
58 |
59 | private void startAnimator2() {
60 | ObjectAnimator animator2 = new ObjectAnimator();
61 | animator2.setTarget(textView2);
62 | animator2.setPropertyName("translationY");
63 | animator2.setFloatValues(0f, -100f);
64 | animator2.setDuration(1000);
65 | animator2.setInterpolator(EasingFunction.BOUNCE_OUT);
66 | animator2.setEvaluator(new FloatEvaluator());
67 | animator2.start();
68 | }
69 |
70 | private void startAnimator1() {
71 | ObjectAnimator animator1 = new ObjectAnimator();
72 | animator1.setTarget(textView1);
73 | animator1.setPropertyName("translationY");
74 | animator1.setFloatValues(0f, -100f);
75 | animator1.setDuration(1000);
76 | animator1.setInterpolator(new LinearInterpolator());
77 | animator1.setEvaluator(EasingFunction.BOUNCE_OUT);
78 | animator1.start();
79 | }
80 | }
81 |
82 |
--------------------------------------------------------------------------------
/example/src/main/java/com/github/hujiaweibujidao/example/activity/BounceActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example.activity;
2 |
3 | import android.animation.FloatEvaluator;
4 | import android.animation.ObjectAnimator;
5 | import android.animation.TimeInterpolator;
6 | import android.animation.TypeEvaluator;
7 | import android.os.Bundle;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.view.View;
10 | import android.view.animation.LinearInterpolator;
11 | import android.widget.Button;
12 | import android.widget.TextView;
13 |
14 | import com.github.hujiaweibujidao.example.R;
15 |
16 | /**
17 | * 演示LinearInterpolator和TypeEvaluator 与 TimeInterpolator和LinearEvaluator 的动画效果一样
18 | * 这里使用ObjectAnimator来验证,弹跳效果
19 | */
20 | public class BounceActivity extends AppCompatActivity {
21 |
22 | TextView textView1;
23 | TextView textView2;
24 | Button buttonStart;
25 | Button buttonStart2;
26 | Button buttonStartAll;
27 |
28 | @Override
29 | protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | setContentView(R.layout.activity_demo);
32 |
33 | textView1 = (TextView) findViewById(R.id.textview1);
34 | textView2 = (TextView) findViewById(R.id.textview2);
35 | buttonStart = (Button) findViewById(R.id.buttonStart1);
36 | buttonStart2 = (Button) findViewById(R.id.buttonStart2);
37 | buttonStartAll = (Button) findViewById(R.id.buttonStartAll);
38 |
39 | buttonStart.setOnClickListener(new View.OnClickListener() {
40 | @Override
41 | public void onClick(View v) {
42 | startAnimator1();
43 | }
44 | });
45 | buttonStart2.setOnClickListener(new View.OnClickListener() {
46 | @Override
47 | public void onClick(View v) {
48 | startAnimator2();
49 | }
50 | });
51 | buttonStartAll.setOnClickListener(new View.OnClickListener() {
52 | @Override
53 | public void onClick(View v) {
54 | startAnimator1();
55 | startAnimator2();
56 | }
57 | });
58 | }
59 |
60 | private void startAnimator2() {
61 | final ObjectAnimator animator2 = new ObjectAnimator();
62 | animator2.setTarget(textView2);
63 | animator2.setPropertyName("translationY");
64 | animator2.setFloatValues(0f, -100f);
65 | animator2.setDuration(1000);
66 | animator2.setInterpolator(new TimeInterpolator() {
67 | @Override
68 | public float getInterpolation(float input) {
69 | if (input < (1 / 2.75))
70 | return (7.5625f * input * input);
71 | else if (input < (2 / 2.75))
72 | return (7.5625f * (input -= (1.5f / 2.75f)) * input + 0.75f);
73 | else if (input < (2.5 / 2.75))
74 | return (7.5625f * (input -= (2.25f / 2.75f)) * input + 0.9375f);
75 | else
76 | return (7.5625f * (input -= (2.625f / 2.75f)) * input + 0.984375f);
77 | }
78 | });
79 | animator2.setEvaluator(new FloatEvaluator());
80 | animator2.start();
81 | }
82 |
83 | private void startAnimator1() {
84 | final ObjectAnimator animator1 = new ObjectAnimator();
85 | animator1.setTarget(textView1);
86 | animator1.setPropertyName("translationY");
87 | animator1.setFloatValues(0f, -100f);
88 | animator1.setDuration(1000);
89 | animator1.setInterpolator(new LinearInterpolator());
90 | animator1.setEvaluator(new TypeEvaluator() {
91 | @Override
92 | public Number evaluate(float fraction, Number startValue, Number endValue) {
93 | float t = animator1.getDuration() * fraction;//已经过去的时间
94 | float b = startValue.floatValue();//起始值
95 | float c = endValue.floatValue() - startValue.floatValue();//结束值与起始值之间的差值
96 | float d = animator1.getDuration();//总的时间间隔,t/d 就是已经过去的时间占总时间间隔的比率
97 |
98 | if ((t /= d) < (1 / 2.75f)) {
99 | return c * (7.5625f * t * t) + b;
100 | } else if (t < (2 / 2.75f)) {
101 | return c * (7.5625f * (t -= (1.5f / 2.75f)) * t + .75f) + b;
102 | } else if (t < (2.5 / 2.75)) {
103 | return c * (7.5625f * (t -= (2.25f / 2.75f)) * t + .9375f) + b;
104 | } else {
105 | return c * (7.5625f * (t -= (2.625f / 2.75f)) * t + .984375f) + b;
106 | }
107 | }
108 | });
109 | animator1.start();
110 | }
111 | }
112 |
113 |
--------------------------------------------------------------------------------
/example/src/main/java/com/github/hujiaweibujidao/example/activity/CustomActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example.activity;
2 |
3 | import android.animation.FloatEvaluator;
4 | import android.animation.ObjectAnimator;
5 | import android.os.Bundle;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.view.View;
8 | import android.view.animation.LinearInterpolator;
9 | import android.widget.Button;
10 | import android.widget.TextView;
11 |
12 | import com.github.hujiaweibujidao.yava.Functions;
13 | import com.github.hujiaweibujidao.yava.IFunction;
14 | import com.github.hujiaweibujidao.example.R;
15 |
16 | /**
17 | * 演示如何自定义function拿到Interpolator或者TypeEvaluator
18 | */
19 | public class CustomActivity extends AppCompatActivity {
20 |
21 | TextView textView1;
22 | TextView textView2;
23 | Button buttonStart;
24 | Button buttonStart2;
25 | Button buttonStartAll;
26 |
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_demo);
31 |
32 | textView1 = (TextView) findViewById(R.id.textview1);
33 | textView2 = (TextView) findViewById(R.id.textview2);
34 | buttonStart = (Button) findViewById(R.id.buttonStart1);
35 | buttonStart2 = (Button) findViewById(R.id.buttonStart2);
36 | buttonStartAll = (Button) findViewById(R.id.buttonStartAll);
37 |
38 | buttonStart.setOnClickListener(new View.OnClickListener() {
39 | @Override
40 | public void onClick(View v) {
41 | startAnimator1();
42 | }
43 | });
44 | buttonStart2.setOnClickListener(new View.OnClickListener() {
45 | @Override
46 | public void onClick(View v) {
47 | startAnimator2();
48 | }
49 | });
50 | buttonStartAll.setOnClickListener(new View.OnClickListener() {
51 | @Override
52 | public void onClick(View v) {
53 | startAnimator1();
54 | startAnimator2();
55 | }
56 | });
57 | }
58 |
59 | private void startAnimator2() {
60 | ObjectAnimator animator2 = new ObjectAnimator();
61 | animator2.setTarget(textView2);
62 | animator2.setPropertyName("translationY");
63 | animator2.setFloatValues(0f, -100f);
64 | animator2.setDuration(1000);
65 | animator2.setInterpolator(Functions.with(new IFunction() {
66 | @Override
67 | public float getValue(float input) {
68 | return input * 2 + 3;
69 | }
70 | }));
71 | animator2.setEvaluator(new FloatEvaluator());
72 | animator2.start();
73 | }
74 |
75 | private void startAnimator1() {
76 | ObjectAnimator animator1 = new ObjectAnimator();
77 | animator1.setTarget(textView1);
78 | animator1.setPropertyName("translationY");
79 | animator1.setFloatValues(0f, -100f);
80 | animator1.setDuration(1000);
81 | animator1.setInterpolator(new LinearInterpolator());
82 | animator1.setEvaluator(Functions.with(new IFunction() {
83 | @Override
84 | public float getValue(float input) {
85 | return input * 2 + 3;
86 | }
87 | }));
88 | animator1.start();
89 | }
90 | }
91 |
92 |
--------------------------------------------------------------------------------
/example/src/main/java/com/github/hujiaweibujidao/example/activity/Demo2Activity.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example.activity;
2 |
3 | import android.animation.TypeEvaluator;
4 | import android.animation.ValueAnimator;
5 | import android.os.Bundle;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.util.Log;
8 | import android.view.View;
9 | import android.view.animation.Interpolator;
10 | import android.view.animation.LinearInterpolator;
11 | import android.widget.Button;
12 |
13 | import com.github.hujiaweibujidao.example.R;
14 |
15 | /**
16 | * 演示LinearInterpolator和TypeEvaluator 与 TimeInterpolator和LinearEvaluator 的动画效果一样
17 | * 这里使用ValueAnimator来验证
18 | */
19 | public class Demo2Activity extends AppCompatActivity {
20 |
21 | Button buttonStart;
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_demo);
27 |
28 | findViewById(R.id.textview1).setVisibility(View.GONE);
29 | findViewById(R.id.textview2).setVisibility(View.GONE);
30 | findViewById(R.id.buttonStart1).setVisibility(View.GONE);
31 | findViewById(R.id.buttonStart2).setVisibility(View.GONE);
32 |
33 | buttonStart = (Button) findViewById(R.id.buttonStartAll);
34 | buttonStart.setText("Click and see your log");
35 |
36 | buttonStart.setOnClickListener(new View.OnClickListener() {
37 | @Override
38 | public void onClick(View v) {
39 |
40 | ValueAnimator animator1 = new ValueAnimator();
41 | animator1.setFloatValues(0.0f, 1.0f);
42 | animator1.setDuration(1000);
43 | animator1.setInterpolator(new LinearInterpolator());//默认就是LinearInterpolator
44 | animator1.setEvaluator(new TypeEvaluator() {
45 | @Override
46 | public Object evaluate(float fraction, Object startValue, Object endValue) {
47 | return (float) startValue + ((float) endValue - (float) startValue) * (fraction*fraction);
48 | }
49 | });
50 | animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
51 | @Override
52 | public void onAnimationUpdate(ValueAnimator animation) {
53 | Log.e("demo 1", "" + animation.getAnimatedValue());
54 | }
55 | });
56 |
57 | ValueAnimator animator2 = new ValueAnimator();
58 | animator2.setFloatValues(0.0f, 1.0f);
59 | animator2.setDuration(1000);
60 | animator2.setInterpolator(new Interpolator() {
61 | @Override
62 | public float getInterpolation(float input) {
63 | return input * input;
64 | }
65 | });
66 | animator2.setEvaluator(new TypeEvaluator() {
67 | @Override
68 | public Object evaluate(float fraction, Object startValue, Object endValue) {
69 | return (float) startValue + ((float) endValue - (float) startValue) * (fraction);
70 | }
71 | });
72 | animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
73 | @Override
74 | public void onAnimationUpdate(ValueAnimator animation) {
75 | Log.e("demo 2", "" + animation.getAnimatedValue());
76 | }
77 | });
78 |
79 | animator1.start();
80 | animator2.start();
81 | }
82 | });
83 |
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/example/src/main/java/com/github/hujiaweibujidao/example/activity/DemoActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example.activity;
2 |
3 | import android.animation.TypeEvaluator;
4 | import android.animation.ValueAnimator;
5 | import android.os.Bundle;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.util.Log;
8 | import android.view.View;
9 | import android.view.animation.Interpolator;
10 | import android.view.animation.LinearInterpolator;
11 | import android.widget.Button;
12 |
13 | import com.github.hujiaweibujidao.example.R;
14 |
15 | /**
16 | * 演示LinearInterpolator和TypeEvaluator 与 TimeInterpolator和LinearEvaluator 的动画效果一样
17 | * 这里使用ValueAnimator来验证
18 | */
19 | public class DemoActivity extends AppCompatActivity {
20 |
21 | Button buttonStart;
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_demo);
27 |
28 | findViewById(R.id.textview1).setVisibility(View.GONE);
29 | findViewById(R.id.textview2).setVisibility(View.GONE);
30 | findViewById(R.id.buttonStart1).setVisibility(View.GONE);
31 | findViewById(R.id.buttonStart2).setVisibility(View.GONE);
32 |
33 | buttonStart = (Button) findViewById(R.id.buttonStartAll);
34 | buttonStart.setText("Click and see your log");
35 |
36 | buttonStart.setOnClickListener(new View.OnClickListener() {
37 | @Override
38 | public void onClick(View v) {
39 | ValueAnimator animator1 = new ValueAnimator();
40 | animator1.setFloatValues(0.0f, 1.0f);
41 | animator1.setDuration(1000);
42 | animator1.setInterpolator(new LinearInterpolator());//传入null也是LinearInterpolator
43 | animator1.setEvaluator(new TypeEvaluator() {
44 | @Override
45 | public Object evaluate(float fraction, Object startValue, Object endValue) {
46 | return 100 * fraction;
47 | }
48 | });
49 | animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
50 | @Override
51 | public void onAnimationUpdate(ValueAnimator animation) {
52 | Log.e("demo 1", "" + animation.getAnimatedValue());
53 | }
54 | });
55 |
56 | ValueAnimator animator2 = new ValueAnimator();
57 | animator2.setFloatValues(0.0f, 1.0f);
58 | animator2.setDuration(1000);
59 | animator2.setInterpolator(new Interpolator() {
60 | @Override
61 | public float getInterpolation(float input) {
62 | return 100 * input;
63 | }
64 | });
65 | animator2.setEvaluator(new TypeEvaluator() {
66 | @Override
67 | public Object evaluate(float fraction, Object startValue, Object endValue) {
68 | return fraction;
69 | }
70 | });
71 | animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
72 | @Override
73 | public void onAnimationUpdate(ValueAnimator animation) {
74 | Log.e("demo 2", "" + animation.getAnimatedValue());
75 | }
76 | });
77 |
78 | animator1.start();
79 | animator2.start();
80 | }
81 | });
82 |
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/example/src/main/java/com/github/hujiaweibujidao/example/activity/EvaluatorActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example.activity;
2 |
3 | import android.animation.ObjectAnimator;
4 | import android.animation.ValueAnimator;
5 | import android.content.Context;
6 | import android.os.Bundle;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.util.DisplayMetrics;
9 | import android.util.TypedValue;
10 | import android.view.View;
11 | import android.widget.AdapterView;
12 | import android.widget.ListView;
13 |
14 | import com.github.hujiaweibujidao.example.R;
15 | import com.github.hujiaweibujidao.example.adapter.EvaluatorAdapter;
16 | import com.github.hujiaweibujidao.yava.EasingFunction;
17 | import com.github.hujiaweibujidao.example.view.EvaluatorView;
18 |
19 | /**
20 | * 演示TypeEvaluator
21 | */
22 | public class EvaluatorActivity extends AppCompatActivity {
23 |
24 | private ListView list;
25 | private EvaluatorAdapter adapter;
26 |
27 | private View circle;
28 | private EvaluatorView evaluatorView;
29 |
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | setContentView(R.layout.activity_evaluator);
34 |
35 | adapter = new EvaluatorAdapter(this);
36 | list = (ListView) findViewById(R.id.list);
37 | list.setAdapter(adapter);
38 | circle = findViewById(R.id.circle);
39 | evaluatorView = (EvaluatorView) findViewById(R.id.drawview);
40 |
41 | list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
42 | @Override
43 | public void onItemClick(AdapterView> adapterView, View view, int position, long l) {
44 | evaluatorView.clear();
45 | circle.setTranslationX(0);
46 | circle.setTranslationY(0);
47 |
48 | ObjectAnimator animator = ObjectAnimator.ofFloat(circle, "translationY", 0, dipToPixels(EvaluatorActivity.this, -(160 - 3)));
49 | animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
50 | @Override
51 | public void onAnimationUpdate(ValueAnimator animation) {
52 | evaluatorView.drawPoint(animation.getCurrentPlayTime(), animation.getDuration(), (float) animation.getAnimatedValue() - dipToPixels(EvaluatorActivity.this, 60));
53 | }
54 | });
55 | animator.setEvaluator(EasingFunction.values()[position]);
56 | animator.setDuration(1200);
57 | animator.start();
58 |
59 | }
60 | });
61 |
62 | }
63 |
64 | public static float dipToPixels(Context context, float dipValue) {
65 | DisplayMetrics metrics = context.getResources().getDisplayMetrics();
66 | return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dipValue, metrics);
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/example/src/main/java/com/github/hujiaweibujidao/example/activity/InterpolatorActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example.activity;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.view.View;
6 | import android.view.Window;
7 | import android.widget.AdapterView;
8 | import android.widget.ListView;
9 |
10 | import com.github.hujiaweibujidao.example.R;
11 | import com.github.hujiaweibujidao.example.adapter.InterpolatorAdapter;
12 |
13 | /**
14 | * 演示Interpolator
15 | */
16 | public class InterpolatorActivity extends AppCompatActivity {
17 |
18 | private static final long DURATION = 2000;
19 |
20 | private ListView listView;
21 | private InterpolatorAdapter adapter;
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | requestWindowFeature(Window.FEATURE_NO_TITLE);
26 |
27 | super.onCreate(savedInstanceState);
28 | setContentView(R.layout.activity_interpolator);
29 |
30 | adapter = new InterpolatorAdapter(this, DURATION);
31 | listView = (ListView) findViewById(R.id.list);
32 | listView.setAdapter(adapter);
33 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
34 | @Override
35 | public void onItemClick(AdapterView> parent, View view, int position, long id) {
36 | adapter.setSelectIndex(position);
37 | }
38 | });
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/example/src/main/java/com/github/hujiaweibujidao/example/activity/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example.activity;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.view.View;
7 |
8 | import com.github.hujiaweibujidao.example.R;
9 |
10 | /**
11 | * 主界面
12 | */
13 | public class MainActivity extends AppCompatActivity {
14 |
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 | super.onCreate(savedInstanceState);
18 | setContentView(R.layout.activity_main);
19 | }
20 |
21 | public void btnInterpolator(View view) {
22 | startActivity(new Intent(this, InterpolatorActivity.class));
23 | }
24 |
25 | public void btnEvaluator(View view) {
26 | startActivity(new Intent(this, EvaluatorActivity.class));
27 | }
28 |
29 | public void btnDemo(View view) {
30 | startActivity(new Intent(this, DemoActivity.class));
31 | }
32 |
33 | public void btnBounce(View view) {
34 | startActivity(new Intent(this, BounceActivity.class));
35 | }
36 |
37 | public void btnBounce2(View view) {
38 | startActivity(new Intent(this, Bounce2Activity.class));
39 | }
40 |
41 | public void btnCustom(View view) {
42 | startActivity(new Intent(this, CustomActivity.class));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/example/src/main/java/com/github/hujiaweibujidao/example/adapter/EvaluatorAdapter.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example.adapter;
2 |
3 | import android.animation.TypeEvaluator;
4 | import android.content.Context;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.BaseAdapter;
9 | import android.widget.TextView;
10 |
11 | import com.github.hujiaweibujidao.example.R;
12 | import com.github.hujiaweibujidao.yava.EasingFunction;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | /**
18 | * TypeEvaluator list adapter
19 | */
20 | public class EvaluatorAdapter extends BaseAdapter {
21 |
22 | private LayoutInflater mInflater;
23 |
24 | private List mNames;
25 | private EasingFunction[] mInterpolators;
26 |
27 | public EvaluatorAdapter(Context context) {
28 | mInflater = LayoutInflater.from(context);
29 |
30 | mInterpolators = EasingFunction.values();
31 | mNames = new ArrayList();
32 | for (EasingFunction function : EasingFunction.values()) {
33 | mNames.add(function.name());
34 | }
35 | }
36 |
37 | @Override
38 | public View getView(int position, View convertView, ViewGroup viewGroup) {
39 | ViewHolder mHolder = null;
40 | if (convertView == null) {
41 | mHolder = new ViewHolder();
42 | convertView = mInflater.inflate(R.layout.item, null);
43 | mHolder.textView = (TextView) convertView.findViewById(R.id.list_item_text);
44 | convertView.setTag(mHolder);
45 | } else {
46 | mHolder = (ViewHolder) convertView.getTag();
47 | }
48 |
49 | TypeEvaluator evaluator = mInterpolators[position];
50 | mHolder.textView.setText(String.format("%s Evaluator", mNames.get(position).replace("_", " ")));
51 | //convertView.setTag(o);//
52 | return convertView;
53 | }
54 |
55 | private class ViewHolder {
56 | public TextView textView;
57 | }
58 |
59 | @Override
60 | public int getCount() {
61 | return mInterpolators == null ? 0 : mInterpolators.length;
62 | }
63 |
64 | @Override
65 | public Object getItem(int position) {
66 | return mInterpolators == null ? null : mInterpolators[position];
67 | }
68 |
69 | @Override
70 | public long getItemId(int position) {
71 | return position;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/example/src/main/java/com/github/hujiaweibujidao/example/adapter/InterpolatorAdapter.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.view.animation.Animation;
8 | import android.view.animation.Interpolator;
9 | import android.view.animation.TranslateAnimation;
10 | import android.widget.BaseAdapter;
11 | import android.widget.RelativeLayout;
12 | import android.widget.RelativeLayout.LayoutParams;
13 | import android.widget.TextView;
14 |
15 | import com.github.hujiaweibujidao.example.R;
16 | import com.github.hujiaweibujidao.yava.EasingFunction;
17 | import com.github.hujiaweibujidao.example.view.CursorView;
18 | import com.github.hujiaweibujidao.example.view.InterpolatorView;
19 |
20 | import java.util.ArrayList;
21 | import java.util.List;
22 |
23 | /**
24 | * Interpolator list adapter
25 | *
26 | */
27 | public class InterpolatorAdapter extends BaseAdapter {
28 |
29 | private int mSelectIndex = -1;
30 | private long mDuration;
31 | private LayoutInflater mInflater;
32 | private List mNames;
33 | private EasingFunction[] mInterpolators;
34 |
35 | public InterpolatorAdapter(Context context, long duration) {
36 | mInflater = LayoutInflater.from(context);
37 | mDuration = duration;
38 |
39 | mInterpolators = EasingFunction.values();
40 | mNames = new ArrayList();
41 | for (EasingFunction function : EasingFunction.values()) {
42 | mNames.add(function.name());
43 | }
44 | }
45 |
46 | @Override
47 | public View getView(int position, View convertView, ViewGroup parent) {
48 | ViewHolder mHolder = null;
49 | if (convertView == null) {
50 | mHolder = new ViewHolder();
51 | convertView = mInflater.inflate(R.layout.adapter, null);
52 | mHolder.interpolatorName = (TextView) convertView.findViewById(R.id.name);
53 | mHolder.interpolatorView = (InterpolatorView) convertView.findViewById(R.id.view);
54 | mHolder.cursor = (CursorView) convertView.findViewById(R.id.cursor);
55 | convertView.setTag(mHolder);
56 | } else {
57 | mHolder = (ViewHolder) convertView.getTag();
58 | }
59 |
60 | final Interpolator interpolator = mInterpolators[position];
61 | mHolder.interpolatorName.setText(String.format("%s Interpolator", mNames.get(position).replace("_", " ")));
62 | mHolder.interpolatorView.setDurationAndInterpolator(mDuration, interpolator);//
63 |
64 | int bottomMargin = mHolder.interpolatorView.blankTB - mHolder.cursor.height / 2;
65 | LayoutParams params = (LayoutParams) mHolder.cursor.getLayoutParams();
66 | params.addRule(RelativeLayout.ALIGN_BOTTOM, R.id.view);
67 | params.bottomMargin = bottomMargin;
68 | mHolder.cursor.setLayoutParams(params);
69 |
70 | //选定项开始做Ease动画,这里操控cursorview使用的只是普通的位移动画而已
71 | if (position == mSelectIndex) {
72 | int toYDelta = mHolder.interpolatorView.height - 2 * mHolder.interpolatorView.blankTB;
73 | Animation anim = new TranslateAnimation(0, 0, 0, -toYDelta);
74 | anim.setDuration(mDuration);
75 | anim.setInterpolator(interpolator);
76 | anim.setStartOffset(300);
77 | mHolder.cursor.startAnimation(anim);
78 | mSelectIndex = -1;
79 | }
80 |
81 | return convertView;
82 | }
83 |
84 | public void setSelectIndex(int index) {
85 | mSelectIndex = index;
86 | notifyDataSetChanged();
87 | }
88 |
89 | private class ViewHolder {
90 | public TextView interpolatorName;
91 | public InterpolatorView interpolatorView;
92 | public CursorView cursor;
93 | }
94 |
95 | @Override
96 | public int getCount() {
97 | return mInterpolators == null ? 0 : mInterpolators.length;
98 | }
99 |
100 | @Override
101 | public Object getItem(int position) {
102 | return mInterpolators == null ? null : mInterpolators[position];
103 | }
104 |
105 | @Override
106 | public long getItemId(int position) {
107 | return position;
108 | }
109 |
110 | }
--------------------------------------------------------------------------------
/example/src/main/java/com/github/hujiaweibujidao/example/view/CursorView.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example.view;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.Path;
8 | import android.util.AttributeSet;
9 | import android.view.View;
10 |
11 | /**
12 | * 指示器
13 | *
14 | * Created by cimi on 15/7/6.
15 | */
16 | public class CursorView extends View {
17 |
18 | public int width;
19 | public int height;
20 |
21 | private Context context;
22 | private Paint paint;
23 | private Path path;
24 |
25 | public CursorView(Context context) {
26 | this(context, null);
27 | }
28 |
29 | public CursorView(Context context, AttributeSet attrs) {
30 | super(context, attrs);
31 | this.context = context;
32 | init();
33 | }
34 |
35 | private void init() {
36 | width = dip2px(20); //from layout
37 | height = dip2px(8); //from layout
38 |
39 | paint = new Paint();
40 | paint.setAntiAlias(true);
41 | paint.setStrokeWidth(1);
42 | paint.setStyle(Paint.Style.FILL);
43 | paint.setColor(Color.RED);
44 |
45 | path = new Path();
46 | path.moveTo(0, height / 2);
47 | path.lineTo(width / 5, 0);
48 | path.lineTo(width, 0);
49 | path.lineTo(width, height);
50 | path.lineTo(width / 5, height);
51 | path.close();
52 | }
53 |
54 | @Override
55 | protected void onDraw(Canvas canvas) {
56 | super.onDraw(canvas);
57 | canvas.drawPath(path, paint);
58 | }
59 |
60 | private int dip2px(float dpValue) {
61 | final float scale = context.getResources()
62 | .getDisplayMetrics().density;
63 | return (int) (dpValue * scale + 0.5f);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/example/src/main/java/com/github/hujiaweibujidao/example/view/EvaluatorView.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * * The MIT License (MIT)
4 | * *
5 | * * Copyright (c) 2014 daimajia
6 | * *
7 | * * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * * of this software and associated documentation files (the "Software"), to deal
9 | * * in the Software without restriction, including without limitation the rights
10 | * * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * * copies of the Software, and to permit persons to whom the Software is
12 | * * furnished to do so, subject to the following conditions:
13 | * *
14 | * * The above copyright notice and this permission notice shall be included in all
15 | * * copies or substantial portions of the Software.
16 | * *
17 | * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | * * SOFTWARE.
24 | *
25 | */
26 |
27 | package com.github.hujiaweibujidao.example.view;
28 |
29 | import android.content.Context;
30 | import android.graphics.Canvas;
31 | import android.graphics.Color;
32 | import android.graphics.Paint;
33 | import android.graphics.Path;
34 | import android.util.AttributeSet;
35 | import android.util.DisplayMetrics;
36 | import android.util.TypedValue;
37 | import android.view.View;
38 |
39 | import java.util.ArrayList;
40 |
41 | /**
42 | * 绘制TypeEvaluator的View
43 | */
44 | public class EvaluatorView extends View {
45 |
46 | private Paint mBackgroundPaint = new Paint();
47 | private Paint mLinePaint = new Paint();
48 | private Path path = new Path();
49 | private boolean start = false;
50 |
51 | private ArrayList mHistory = new ArrayList();
52 |
53 | {
54 | mBackgroundPaint.setColor(Color.WHITE);
55 | mLinePaint.setColor(Color.rgb(77, 83, 96));
56 | mLinePaint.setAntiAlias(true);
57 | mLinePaint.setStrokeWidth((float) 3.0);
58 | mLinePaint.setStyle(Paint.Style.STROKE);
59 | }
60 |
61 | public EvaluatorView(Context context) {
62 | super(context);
63 | }
64 |
65 | public EvaluatorView(Context context, AttributeSet attrs) {
66 | super(context, attrs);
67 | }
68 |
69 | public EvaluatorView(Context context, AttributeSet attrs, int defStyleAttr) {
70 | super(context, attrs, defStyleAttr);
71 | }
72 |
73 | @Override
74 | protected void onDraw(Canvas canvas) {
75 | super.onDraw(canvas);
76 | float l = 0;
77 | float t = getHeight() - getPaddingBottom() - dipToPixels(getContext(), 217);
78 | float r = getWidth() - getPaddingRight();
79 | float b = getHeight() - dipToPixels(getContext(), 60);
80 | canvas.drawRect(l, t, r, b, mLinePaint);
81 | canvas.drawPath(path, mLinePaint);
82 | }
83 |
84 | public static float dipToPixels(Context context, float dipValue) {
85 | DisplayMetrics metrics = context.getResources().getDisplayMetrics();
86 | return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dipValue, metrics);
87 | }
88 |
89 | public void drawPoint(float time, float duration, float y) {
90 | float p = time / duration;
91 | float x = p * getWidth();
92 | float z = getHeight() + y;
93 | if (!start) {
94 | path.moveTo(x, z);
95 | start = true;
96 | }
97 | path.lineTo(x, z);
98 | invalidate();
99 | }
100 |
101 | public void clear() {
102 | path.reset();
103 | start = false;
104 | invalidate();
105 | }
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/example/src/main/java/com/github/hujiaweibujidao/example/view/InterpolatorView.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example.view;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.Path;
8 | import android.util.AttributeSet;
9 | import android.view.View;
10 | import android.view.animation.Interpolator;
11 |
12 | /**
13 | * 函数曲线图
14 | *
15 | * Created by cimi on 15/7/6.
16 | */
17 | public class InterpolatorView extends View {
18 |
19 | public int width;
20 | public int height;
21 | public int blankTB;//blank of top or bottom
22 | public int blankLR;//blank of left or right
23 |
24 | private Context context;
25 | private Paint linePaint;
26 | private Paint pathPaint;
27 | private Path path;
28 |
29 | public InterpolatorView(Context context) {
30 | this(context, null);
31 | }
32 |
33 | public InterpolatorView(Context context, AttributeSet attrs) {
34 | super(context, attrs);
35 | this.context = context;
36 | init();
37 | }
38 |
39 | private void init() {
40 | width = dip2px(100); //from layout, 100dp
41 | height = dip2px(100); //from layout
42 | blankTB = height * 2 / 7;//why?
43 | blankLR = 0;
44 |
45 | linePaint = new Paint();
46 | linePaint.setAntiAlias(true);
47 | linePaint.setStrokeWidth(1);
48 | linePaint.setStyle(Paint.Style.STROKE);
49 | linePaint.setColor(Color.DKGRAY);
50 |
51 | pathPaint = new Paint();
52 | pathPaint.setAntiAlias(true);
53 | pathPaint.setStrokeWidth(2);
54 | pathPaint.setStyle(Paint.Style.STROKE);
55 | pathPaint.setColor(Color.RED);
56 |
57 | path = new Path();
58 | }
59 |
60 | public void setDurationAndInterpolator(long duration, Interpolator interpolator) {
61 | if (duration <= 0)
62 | return;
63 | if (interpolator == null)
64 | return;
65 |
66 | int w = width - blankLR * 2;
67 | int h = height - blankTB * 2;
68 |
69 | path.reset();
70 | path.moveTo(blankLR, height - blankTB);
71 | int factor = (int) (duration / w + (duration % w > 0 ? 1 : 0));
72 | int i = 0;
73 | for (; i < duration; i += factor) {
74 | path.lineTo(i / factor + blankLR, h - interpolator.getInterpolation((float) i / duration) * h + blankTB);
75 | }
76 |
77 | // if (!(interpolator instanceof EaseBreathInterpolator))
78 | // path.lineTo(i / factor + blankLR, blankTB);
79 |
80 | invalidate();
81 | }
82 |
83 | @Override
84 | protected void onDraw(Canvas canvas) {
85 | canvas.drawLine(0, blankTB, width, blankTB, linePaint);//float startX, float startY, float stopX, float stopY, Paint paint
86 | canvas.drawLine(0, height - blankTB, width, height - blankTB, linePaint);
87 |
88 | canvas.drawPath(path, pathPaint);
89 | }
90 |
91 | private int dip2px(float dpValue) {
92 | final float scale = context.getResources().getDisplayMetrics().density;
93 | return (int) (dpValue * scale + 0.5f);
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/example/src/main/res/drawable/circle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/example/src/main/res/layout/activity_demo.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
19 |
20 |
29 |
30 |
40 |
41 |
42 |
43 |
49 |
50 |
55 |
56 |
62 |
63 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/example/src/main/res/layout/activity_evaluator.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
22 |
23 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/example/src/main/res/layout/activity_interpolator.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/example/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
19 |
20 |
27 |
28 |
35 |
36 |
43 |
44 |
51 |
52 |
59 |
60 |
67 |
68 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/example/src/main/res/layout/adapter.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
19 |
20 |
26 |
27 |
35 |
36 |
--------------------------------------------------------------------------------
/example/src/main/res/layout/item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/example/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/javayhu/yava/ca558f24c15b584eb463054620ea3efc85700e91/example/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/javayhu/yava/ca558f24c15b584eb463054620ea3efc85700e91/example/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/javayhu/yava/ca558f24c15b584eb463054620ea3efc85700e91/example/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/javayhu/yava/ca558f24c15b584eb463054620ea3efc85700e91/example/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/javayhu/yava/ca558f24c15b584eb463054620ea3efc85700e91/example/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/example/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/example/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/example/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Yava
3 |
4 |
--------------------------------------------------------------------------------
/example/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/example/src/test/java/com/github/hujiaweibujidao/example/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.example;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/javayhu/yava/ca558f24c15b584eb463054620ea3efc85700e91/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | apply plugin: 'com.github.dcendents.android-maven'
4 |
5 | group='com.github.hujiaweibujidao'
6 |
7 | android {
8 | compileSdkVersion 23
9 | buildToolsVersion "23.0.3"
10 |
11 | defaultConfig {
12 | minSdkVersion 16
13 | targetSdkVersion 23
14 | versionCode 1
15 | versionName "1.0.0"
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | compile fileTree(dir: 'libs', include: ['*.jar'])
27 | testCompile 'junit:junit:4.12'
28 | compile 'com.android.support:appcompat-v7:23.4.0'
29 | }
30 |
--------------------------------------------------------------------------------
/library/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/hujiawei/Android/android_sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/library/src/androidTest/java/com/github/hujiaweibujidao/yava/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.yava;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/library/src/main/java/com/github/hujiaweibujidao/yava/AbstractFunction.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.yava;
2 |
3 | import android.animation.TypeEvaluator;
4 | import android.view.animation.Interpolator;
5 |
6 | /**
7 | * 抽象函数实现,既可以当做简单函数使用,也可以当做Interpolator或者TypeEvaluator去用于制作动画
8 | */
9 | public abstract class AbstractFunction implements IFunction, Interpolator, TypeEvaluator {
10 |
11 | @Override
12 | public float getInterpolation(float input) {
13 | return getValue(input);
14 | }
15 |
16 | @Override
17 | public Float evaluate(float fraction, Float startValue, Float endValue) {
18 | return startValue + getValue(fraction) * (endValue - startValue);
19 | }
20 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/github/hujiaweibujidao/yava/EasingFunction.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.yava;
2 |
3 | import android.animation.TypeEvaluator;
4 | import android.view.animation.Interpolator;
5 |
6 |
7 | /**
8 | * 常见的30个缓动函数的实现
9 | *
10 | * @author hujiawei 16/5/27
11 | */
12 | public enum EasingFunction implements IFunction, Interpolator, TypeEvaluator {
13 |
14 | /* ------------------------------------------------------------------------------------------- */
15 | /* BACK
16 | /* ------------------------------------------------------------------------------------------- */
17 | BACK_IN {
18 | @Override
19 | public float getValue(float input) {
20 | return input * input * ((1.70158f + 1) * input - 1.70158f);
21 | }
22 | },
23 | BACK_OUT {
24 | @Override
25 | public float getValue(float input) {
26 | return ((input = input - 1) * input * ((1.70158f + 1) * input + 1.70158f) + 1);
27 | }
28 | },
29 | BACK_INOUT {
30 | @Override
31 | public float getValue(float input) {
32 | float s = 1.70158f;
33 | if ((input *= 2) < 1) {
34 | return 0.5f * (input * input * (((s *= (1.525f)) + 1) * input - s));
35 | }
36 | return 0.5f * ((input -= 2) * input * (((s *= (1.525f)) + 1) * input + s) + 2);
37 | }
38 | },
39 |
40 | /* ------------------------------------------------------------------------------------------- */
41 | /* BOUNCE
42 | /* ------------------------------------------------------------------------------------------- */
43 | BOUNCE_IN {
44 | @Override
45 | public float getValue(float input) {
46 | input = 1 - input;
47 | if (input < (1 / 2.75))
48 | return 1 - (7.5625f * input * input);
49 | else if (input < (2 / 2.75))
50 | return 1 - (7.5625f * (input -= (1.5f / 2.75f)) * input + 0.75f);
51 | else if (input < (2.5 / 2.75))
52 | return 1 - (7.5625f * (input -= (2.25f / 2.75f)) * input + 0.9375f);
53 | else
54 | return 1 - (7.5625f * (input -= (2.625f / 2.75f)) * input + 0.984375f);
55 | }
56 | },
57 | BOUNCE_OUT {
58 | @Override
59 | public float getValue(float input) {
60 | if (input < (1 / 2.75))
61 | return (7.5625f * input * input);
62 | else if (input < (2 / 2.75))
63 | return (7.5625f * (input -= (1.5f / 2.75f)) * input + 0.75f);
64 | else if (input < (2.5 / 2.75))
65 | return (7.5625f * (input -= (2.25f / 2.75f)) * input + 0.9375f);
66 | else
67 | return (7.5625f * (input -= (2.625f / 2.75f)) * input + 0.984375f);
68 | }
69 | },
70 | BOUNCE_INOUT {
71 | @Override
72 | public float getValue(float input) {
73 | if ((input) < 0.5f) {
74 | input = input * 2;
75 | input = 1 - input;
76 | if (input < (1 / 2.75))
77 | return (1 - (7.5625f * input * input)) * 0.5f;
78 | else if (input < (2 / 2.75))
79 | return (1 - (7.5625f * (input -= (1.5f / 2.75f)) * input + 0.75f)) * 0.5f;
80 | else if (input < (2.5 / 2.75))
81 | return (1 - (7.5625f * (input -= (2.25f / 2.75f)) * input + 0.9375f)) * 0.5f;
82 | else
83 | return (1 - (7.5625f * (input -= (2.625f / 2.75f)) * input + 0.984375f)) * 0.5f;
84 | } else {
85 | input = input * 2 - 1;
86 | if (input < (1 / 2.75))
87 | return ((7.5625f * input * input)) * 0.5f + 1 * 0.5f;
88 | else if (input < (2 / 2.75))
89 | return ((7.5625f * (input -= (1.5f / 2.75f)) * input + 0.75f)) * 0.5f + 1 * 0.5f;
90 | else if (input < (2.5 / 2.75))
91 | return ((7.5625f * (input -= (2.25f / 2.75f)) * input + 0.9375f)) * 0.5f + 1 * 0.5f;
92 | else
93 | return ((7.5625f * (input -= (2.625f / 2.75f)) * input + 0.984375f)) * 0.5f + 1 * 0.5f;
94 | }
95 | }
96 | },
97 |
98 | /* ------------------------------------------------------------------------------------------- */
99 | /* CIRCULAR
100 | /* ------------------------------------------------------------------------------------------- */
101 | CIRCULAR_IN {
102 | @Override
103 | public float getValue(float input) {
104 | return (float) (-1 * (Math.sqrt(1 - input * input) - 1.0f));
105 | }
106 | },
107 | CIRCULAR_OUT {
108 | @Override
109 | public float getValue(float input) {
110 | return (float) (Math.sqrt(1 - (input - 1) * (input - 1)));
111 | }
112 | },
113 | CIRCULAR_INOUT {
114 | @Override
115 | public float getValue(float input) {
116 | if ((input /= 0.5) < 1) {
117 | return (float) (-1 * 0.5 * (Math.sqrt(1 - input * input) - 1));
118 | }
119 | return (float) (0.5 * (Math.sqrt(1 - (input -= 2) * input) + 1));
120 | }
121 | },
122 |
123 | /* ------------------------------------------------------------------------------------------- */
124 | /* ELASTIC //todo duration 3
125 | /* ------------------------------------------------------------------------------------------- */
126 | ELASTIC_IN {
127 | @Override
128 | public float getValue(float input) {
129 | float mDuration = getDuration() / 1000f;
130 | float s;
131 | float p = 0.0f;
132 | float a = 0.0f;
133 | if (input == 0) {
134 | return 0;
135 | }
136 | if (input == 1) {
137 | return 1;
138 | }
139 | if (p == 0) {
140 | p = mDuration * 0.3f;
141 | }
142 | if (a == 0 || (1 > 0 && a < 1) || (1 < 0 /*&& a < -1*/)) {
143 | a = 1;
144 | s = p / 4;
145 | } else {
146 | s = (float) (p / TWO_PI * Math.asin(1 / a));
147 | }
148 | return (float) (-(a * Math.pow(2, 10 * (input -= 1)) * Math.sin((input * mDuration - s) * TWO_PI / p)) + 0);
149 | }
150 | },
151 | ELASTIC_OUT {
152 | @Override
153 | public float getValue(float input) {
154 | float mDuration = getDuration() / 1000f;
155 | float s;
156 | float p = 0.0f;
157 | float a = 0.0f;
158 | if (input == 0) {
159 | return 0;
160 | }
161 | if (input == 1) {
162 | return 1;
163 | }
164 | if (p == 0) {
165 | p = mDuration * 0.3f;
166 | }
167 | if (a == 0 || (1 > 0 && a < 1) || (1 < 0 /*&& a < -1*/)) {
168 | a = 1;
169 | s = p / 4;
170 | } else {
171 | s = (float) (p / TWO_PI * Math.asin(1 / a));
172 | }
173 | return (float) (a * Math.pow(2, -10 * input) * Math.sin((input * mDuration - s) * TWO_PI / p) + 1 + 0);
174 | }
175 | },
176 | ELASTIC_INOUT {
177 | @Override
178 | public float getValue(float input) {
179 | float mDuration = getDuration() / 1000f;
180 | float s;
181 | float p = 0.0f;
182 | float a = 0.0f;
183 | if (input == 0) {
184 | return 0;
185 | }
186 | if ((input /= 0.5) == 2) {
187 | return 1;
188 | }
189 | if (p == 0) {
190 | p = mDuration * (0.3f * 1.5f);
191 | }
192 | if (a == 0 || (1 > 0 && a < 1) || (1 < 0 /*&& a < -1*/)) {
193 | a = 1;
194 | s = p / 4;
195 | } else {
196 | s = (float) (p / TWO_PI * Math.asin(1 / a));
197 | }
198 | if (input < 1) {
199 | return (float) (-0.5 * (a * Math.pow(2, 10 * (input -= 1)) * Math.sin((input * mDuration - s) * TWO_PI / p)) + 0);
200 | }
201 | return (float) (a * Math.pow(2, -10 * (input -= 1)) * Math.sin((input * mDuration - s) * TWO_PI / p) * .5 + 1 + 0);
202 | }
203 | },
204 |
205 | /* ------------------------------------------------------------------------------------------- */
206 | /* EXPO
207 | /* ------------------------------------------------------------------------------------------- */
208 | EXPO_IN {
209 | @Override
210 | public float getValue(float input) {
211 | return (float) ((input == 0) ? 0 : 1 * Math.pow(2, 10 * (input - 1)) - 0.001f);
212 | }
213 | },
214 | EXPO_OUT {
215 | @Override
216 | public float getValue(float input) {
217 | return (float) ((input == 1) ? 1 : (-Math.pow(2, -10 * input) + 1));
218 | }
219 | },
220 | EXPO_INOUT {
221 | @Override
222 | public float getValue(float input) {
223 | if (input == 0) {
224 | return 0;
225 | }
226 | if (input == 1) {
227 | return 1;
228 | }
229 | if ((input /= 0.5f) < 1) {
230 | return (float) (0.5f * Math.pow(2, 10 * (input - 1)));
231 | }
232 | return (float) (0.5f * (-Math.pow(2, -10 * --input) + 2));
233 | }
234 | },
235 |
236 | /* ------------------------------------------------------------------------------------------- */
237 | /* QUAD
238 | /* ------------------------------------------------------------------------------------------- */
239 | QUAD_IN {
240 | @Override
241 | public float getValue(float input) {
242 | return input * input;
243 | }
244 | },
245 | QUAD_OUT {
246 | @Override
247 | public float getValue(float input) {
248 | return -input * (input - 2);
249 | }
250 | },
251 | QUAD_INOUT {
252 | @Override
253 | public float getValue(float input) {
254 | if ((input /= 0.5f) < 1) {
255 | return 0.5f * input * input;
256 | }
257 | return -0.5f * ((--input) * (input - 2) - 1);
258 | }
259 | },
260 |
261 | /* ------------------------------------------------------------------------------------------- */
262 | /* CUBIC
263 | /* ------------------------------------------------------------------------------------------- */
264 | CUBIC_IN {
265 | @Override
266 | public float getValue(float input) {
267 | return input * input * input;
268 | }
269 | },
270 | CUBIC_OUT {
271 | @Override
272 | public float getValue(float input) {
273 | return (input - 1) * (input - 1) * (input - 1) + 1;
274 | }
275 | },
276 | CUBIC_INOUT {
277 | @Override
278 | public float getValue(float input) {
279 | if ((input /= 0.5f) < 1) {
280 | return 0.5f * input * input * input;
281 | }
282 | return 0.5f * ((input -= 2) * input * input + 2);
283 | }
284 | },
285 |
286 | /* ------------------------------------------------------------------------------------------- */
287 | /* QUART
288 | /* ------------------------------------------------------------------------------------------- */
289 | QUART_IN {
290 | @Override
291 | public float getValue(float input) {
292 | return input * input * input * input;
293 | }
294 | },
295 | QUART_OUT {
296 | @Override
297 | public float getValue(float input) {
298 | return 1 - (input - 1) * (input - 1) * (input - 1) * (input - 1);
299 | }
300 | },
301 | QUART_INOUT {
302 | @Override
303 | public float getValue(float input) {
304 | if ((input /= 0.5f) < 1) {
305 | return 0.5f * input * input * input * input;
306 | }
307 | return -0.5f * ((input -= 2) * input * input * input - 2);
308 | }
309 | },
310 |
311 | /* ------------------------------------------------------------------------------------------- */
312 | /* QUINT
313 | /* ------------------------------------------------------------------------------------------- */
314 | QUINT_IN {
315 | @Override
316 | public float getValue(float input) {
317 | return input * input * input * input * input;
318 | }
319 | },
320 | QUINT_OUT {
321 | @Override
322 | public float getValue(float input) {
323 | return (input - 1) * (input - 1) * (input - 1) * (input - 1) * (input - 1) + 1;
324 | }
325 | },
326 | QUINT_INOUT {
327 | @Override
328 | public float getValue(float input) {
329 | if ((input /= 0.5f) < 1) {
330 | return 0.5f * input * input * input * input * input;
331 | }
332 | return 0.5f * ((input -= 2) * input * input * input * input + 2);
333 | }
334 | },
335 |
336 | /* ------------------------------------------------------------------------------------------- */
337 | /* SINE
338 | /* ------------------------------------------------------------------------------------------- */
339 | SINE_IN {
340 | @Override
341 | public float getValue(float input) {
342 | return (float) (-1 * Math.cos(input * HALF_PI) + 1);
343 | }
344 | },
345 | SINE_OUT {
346 | @Override
347 | public float getValue(float input) {
348 | return (float) Math.sin(input * HALF_PI);
349 | }
350 | },
351 | SINE_INOUT {
352 | @Override
353 | public float getValue(float input) {
354 | return (float) (-1 * 0.5f * (Math.cos(PI * input) - 1));
355 | }
356 | },
357 |
358 | /* ------------------------------------------------------------------------------------------- */
359 | /* BREATH
360 | /* ------------------------------------------------------------------------------------------- */
361 | BREATH {
362 | @Override
363 | public float getValue(float input) {
364 | if (input < 0.333) {
365 | return (float) (0.5f + 0.5f * Math.sin(input * 3.0f * Math.PI - Math.PI * 0.5f));
366 | } else {
367 | return (float) Math.pow((0.5 * Math.sin(-3f * Math.PI * input * 0.5f + Math.PI) + 0.5f), 2);
368 | }
369 | }
370 | };
371 |
372 | //如果这个function在求值的时候需要duration作为参数的话,那么可以通过setDuration来设置,否则使用默认值
373 | private float duration = 1000f;//目前只有ELASTIC***这三个是需要duration的,其他的都不需要
374 |
375 | public float getDuration() {
376 | return duration;
377 | }
378 |
379 | public EasingFunction setDuration(float duration) {
380 | this.duration = duration;
381 | return this;
382 | }
383 |
384 | //将Function当做Interpolator使用,默认的实现,不需要枚举元素去重新实现
385 | @Override
386 | public float getInterpolation(float input) {
387 | return getValue(input);
388 | }
389 |
390 | //将Function当做TypeEvaluator使用,默认的实现,不需要枚举元素去重新实现
391 | @Override
392 | public Float evaluate(float fraction, Float startValue, Float endValue) {
393 | return startValue + getValue(fraction) * (endValue - startValue);
394 | }
395 |
396 | //几个数学常量
397 | public static final float PI = (float) Math.PI;
398 | public static float TWO_PI = PI * 2.0f;
399 | public static float HALF_PI = PI * 0.5f;
400 | }
401 |
--------------------------------------------------------------------------------
/library/src/main/java/com/github/hujiaweibujidao/yava/Functions.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.yava;
2 |
3 |
4 | /**
5 | * 工具类,将自定义的函数快速封装成AbstractFunction
6 | */
7 | public class Functions {
8 |
9 | public static AbstractFunction with(final IFunction function) {
10 | return new AbstractFunction() {
11 | @Override
12 | public float getValue(float input) {
13 | return function.getValue(input);
14 | }
15 | };
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/library/src/main/java/com/github/hujiaweibujidao/yava/IFunction.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.yava;
2 |
3 | /**
4 | * 函数接口:给定输入,得到输出
5 | */
6 | public interface IFunction {
7 | float getValue(float input);
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | yava
4 |
--------------------------------------------------------------------------------
/library/src/test/java/com/github/hujiaweibujidao/yava/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.github.hujiaweibujidao.yava;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':example', ':library'
2 |
--------------------------------------------------------------------------------
/yava.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/javayhu/yava/ca558f24c15b584eb463054620ea3efc85700e91/yava.gif
--------------------------------------------------------------------------------