时间紧张,先记一笔,后续优化与完善。
在Android 里你能够应用的动画效果:
以上动画的基本应用就是本文的内容了。由于,本人的能力问题,其实弄不出让人眼前一亮的动画,就凑合着看着吧。不过,那些使人赞叹的动画效果的基础就是这些。
一般而言,要做动画的,须要封点缀物理公式,用作为计算帧与帧间的数值计算,不过,如果,只是,为了弄些动画让app好用一些,倒不须要弄得这么复杂,android 官方api 已封装好了一些经常使用的动画插值器。
默许内置7种类型的插值器,个人认为,如果只是应用里面的一些动画的话这7个就够用了。
-
AccelerateInterpolator
减速
-
Decelerate
减速
-
AccelerateDecelerateInterpolator
开始,和开头都很慢,但是,中间减速
-
AnticipateInterpolator
开始向后一点,然后,往前抛
-
OvershootInterpolator
往前抛超越一点,然后返返来
-
AnticipateOvershootInterpolator
开始向后一点,往前抛过点,然后返返来
-
BounceInterpolator
结束的时候弹一下
-
LinearInterpolator
匀速
以上动画都源自android官方api demo,用eclipse adt android 选择例子项目导航,然后,选择APIDEMOS 就能创建(什么没听说过?当初知道了吧。。。)
好了,虽然截取的gif 动画播放起来有点抽筋的感觉,接上去我们该如安在应用中应用这些知识呢?
目前讲授动画api 的资料比较多,这里就不在重复那些基础的知识了!
当初让我们学习一下,如何利用,平移,缩放,旋转创造出让人眼前一亮的动画.
为了,更有目标的应用动画,上面假想一个应用场景。
假想:商品购物车案例
Notice :为了方便看效果,动画延时时间将会设置的比较长。特地说明一下:假想就是随意想,切勿对号入座。
任务:
为了,让商城app有更好的交互效果,决定对购物车控件和商品控件上面加一些动画效果。
购物车动画设计方案:
利用,透明,平移,对购物车的涌现和离开增长动画交互效果。
经过一番尽力效果如下(凑合着看吧。。):
相干知识点
一些动画经常使用的通用基础属性:
Notice: 所谓通用就是说全部动画标签都适用于这些属性
-
android:duration
设置动画播放的时间
-
android:startOffset
设置动画的开始播放时间
-
andorid:interpolator
设置动画的插值器
-
android:repeatCount
动画播放的经常使用次数
-
android:repeatMode
动画重播的模式,即从头至尾,从头至尾,还是从头至尾,在从尾到头。
透明的应用:
<alpha />
value 从 0 (透明) 到 1 (不透明)在android中透明主要用于对view 淡入,淡出的效果控制主要有两个属性
平移的应用:
<translate />
支持应用 %,如 “50%“ 获取的是这个view的百分之50,除此之外还有另外一种写法:”50%p“ 意思是获取这个view的上一级view的百分之50 当然,指定特定值也是支持的“22.2”,不过为了兼容更多的android设备建议还是应用百分比的值。
-
android:fromXDelta
-
android:fromYDelta
from?Delta 意思是开始的轴线
-
android:toXDelta
-
android:toYDelta
to?Delta 意思是结束的轴线
此次的方案展示了两个插值器的应用:
用于涌现的:BounceInterpolator
用于离开的: AnticipateInterpolator
所谓插值器就是用于数值的起始间的变化,就是相当于一个类似于物理引擎的货色。android官方内置了一些简单经常使用的数值变换,让我们,不须要去学习相干的物理知识。
例如:
开始值为1,结束值为 100.那么我们如何控制变化这个值的变化过程呢?这里就是插值器的应用。
一般匀速的话就是:
1,2,3,4,5...100。 然后我们就会看到物体以一个匀速的速度进行平移操纵。
那么我们须要物体像汽车那样减速度的前进,我们可以用减速插值器,我们从1到100的过程,就会是:
1,2,4,5,8,16.。。。。100 展示在我们面前的view对象就会以一个减速度的形式进行平移。
有很多应用开发者并不熟悉动画制作的一些基础知识,可能不太明确。当初,通过对源码进行分析,来完全弄明确这个观点。
我们分析一些Interpolator 类树:
从api文档TimeInterpolator 我们可以知道,这个插值器的实现只有一个方法:
getInterpolation(float t);
然后我们挑选前面用过的BounceInterpolator 看下,它是如何实现这个方法。如果感兴趣的,可以按照这类方法,把其他几个插值器的实现都看一遍。
最后我们会发明,插值器的作用就是返回值。
接着我们来看下Animation line:869 是怎么用这个接口的.
看完这这几个地方,相信应该对android 动画框架怎么对值进行变换的道理应该有所懂得。
有了以上知识,我们对android的动画框架基本上已完整懂得,当初,我们利用学到的知识,进行更好的动画设计。
我们接着刚才的案例,动手设计商品控件的动画设计
商品动画设计:
此次,我们学习一个新的动画标签缩放(<scale>
)
效果如下:
<scale />
使view 大点或者小点
-
android:fromXScale
-
android:fromYScale
from?Scale 意思是开始轴线的缩放比例(默许 1.0)
-
android:toXScale
-
android:toYScale
to?Scale 意思是结束轴线的缩放比例(默许 1.0)
-
android:pivotX
-
android:pivotX
旋转用的轴点坐标
最后我们把购物车的动画,和商品的动画在组合起来。效果如下:
添加商品的时候,如果购物车还没涌现,先涌现购物车显示的动画,在进行商品的动画播放。
此次我们学习一下如何监听动画的动作,对于AnimationListener()
主要有三个
-
onAnimationStart(Animation animation)
-
onAnimationRepeat(Animation animation)
-
onAnimationEnd(Animation animation)
每日一道理
青春是用意志的血滴和拼搏的汗水酿成的琼浆——历久弥香;青春是用不凋的希望和不灭的向往编织的彩虹——绚丽辉煌;青春是用永恒的执著和顽强的韧劲筑起的一道铜墙铁壁——固若金汤。
package
com
.
youxiachai
.
animutils
.
example
;
import
android.app.Activity
;
import
android.graphics.Color
;
import
android.os.Bundle
;
import
android.os.Handler
;
import
android.view.Gravity
;
import
android.view.View
;
import
android.view.View.OnClickListener
;
import
android.view.ViewGroup
;
import
android.view.ViewGroup.LayoutParams
;
import
android.view.animation.Animation
;
import
android.view.animation.Animation.AnimationListener
;
import
android.view.animation.AnimationUtils
;
import
android.widget.Button
;
import
android.widget.LinearLayout
;
import
android.widget.TextView
;
/**
* @author youxiachai
* @date 2013-5-30
*/
public
class
MainActivity
extends
Activity
{
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_main
);
findViewById
(
R
.
id
.
bShopcart
).
setOnClickListener
(
new
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
// TODO Auto-generated method stub
if
(
getShopCart
()
==
null
){
showShopCart
();
}
else
{
hideShopCart
((
ViewGroup
)
findViewById
(
R
.
id
.
shopcart
));
}
}
});
findViewById
(
R
.
id
.
bShop
).
setOnClickListener
(
new
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
//TODO Auto-generated method stub
addShop
();
}
});
}
/**播放view 的动画
* @param v
* @param id
*/
private
void
startViewAnimation
(
View
v
,
int
id
){
Animation
animation
=
AnimationUtils
.
loadAnimation
(
this
,
id
);
v
.
startAnimation
(
animation
);
}
private
void
addShop
(){
if
(
getShopCart
()
!=
null
){
// getScene().removeView(v);
// getScene().addView(v);
// startViewAnimation(v, R.anim.block_move_right);
Button
b
=
new
Button
(
this
);
ViewGroup
.
LayoutParams
lp
=
new
LayoutParams
(
200
,
50
);
b
.
setText
(
"xxx"
);
b
.
setLayoutParams
(
lp
);
getShopCart
().
addView
(
b
);
startViewAnimation
(
b
,
R
.
anim
.
block_move_right
);
}
else
{
Animation
shopCartAnim
=
AnimationUtils
.
loadAnimation
(
this
,
R
.
anim
.
in_translate_top
);
shopCartAnim
.
setAnimationListener
(
new
AnimationListener
()
{
@Override
public
void
onAnimationStart
(
Animation
animation
)
{
// TODO Auto-generated method stub
}
@Override
public
void
onAnimationRepeat
(
Animation
animation
)
{
// TODO Auto-generated method stub
}
@Override
public
void
onAnimationEnd
(
Animation
animation
)
{
// TODO Auto-generated method stub
new
Handler
().
postDelayed
(
new
Runnable
()
{
@Override
public
void
run
()
{
// TODO Auto-generated method stub
addShop
();
}
},
500
);
}
});
View
v
=
buildShopCart
();
getScene
().
addView
(
v
);
v
.
startAnimation
(
shopCartAnim
);
}
}
private
ViewGroup
getShopCart
(){
return
(
ViewGroup
)
findViewById
(
R
.
id
.
shopcart
);
}
/**
* 显示购物车
*/
private
void
showShopCart
(){
View
v
=
buildShopCart
();
//利用@android:anim/bounce_interpolator 涌现的时候弹一下
startViewAnimation
(
v
,
R
.
anim
.
in_translate_top
);
getScene
().
addView
(
v
);
}
/**隐藏购物车
* @param v
*/
private
void
hideShopCart
(
ViewGroup
v
){
TextView
tv
=
(
TextView
)
v
.
getChildAt
(
0
);
tv
.
setText
(
"向下一点,然后往顶部抛离开"
);
// 利用 @android:anim/anticipate_interpolator 向下一点,然后离开
startViewAnimation
(
v
,
R
.
anim
.
out_translate_top
);
getScene
().
removeView
(
v
);
}
/**创建购物车对象
* @return
*/
private
View
buildShopCart
(){
LinearLayout
ll
=
new
LinearLayout
(
this
);
ll
.
setOrientation
(
LinearLayout
.
VERTICAL
);
TextView
tv
=
new
TextView
(
this
);
tv
.
setTextColor
(
Color
.
WHITE
);
tv
.
setText
(
"从顶部上去,到底部的时候弹一下"
);
ll
.
setId
(
R
.
id
.
shopcart
);
LinearLayout
.
LayoutParams
lp
=
new
LinearLayout
.
LayoutParams
(
400
,
400
);
lp
.
setMargins
(
0
,
10
,
0
,
0
);
ll
.
setBackgroundColor
(
getResources
().
getColor
(
R
.
color
.
pink
));
ll
.
setLayoutParams
(
lp
);
ll
.
setGravity
(
Gravity
.
CENTER
);
ll
.
addView
(
tv
);
return
ll
;
}
/**获得动画播放view group
* @return
*/
private
ViewGroup
getScene
(){
return
(
ViewGroup
)
findViewById
(
R
.
id
.
animContext
);
}
}
//////////////////////////////////
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:interpolator=
"@android:anim/bounce_interpolator"
>
<alpha
android:duration=
"2000"
android:fromAlpha=
"0"
android:toAlpha=
"1"
/>
<translate
android:duration=
"2000"
android:fromXDelta=
"0"
android:fromYDelta=
"-100%"
android:toXDelta=
"0"
android:toYDelta=
"0"
/>
</set>
////////////////////////////////
文章结束给大家分享下程序员的一些笑话语录: 一条狗在街上闲逛,看见橱窗里一张告示:「招聘程序员。会编程,有团队精神,至少精通两种语言。均等机会。」
那条狗就进去申请,但是被拒绝了。
「我不能雇一条狗在公司里做事。」经理说。
狗不服气,指着告示上「均等机会」几字抗议。
经理没法,叹了口气,不屑地问道:「你会编程吗?」
那条狗默默地走到电脑前,编了个程序,运作准确。
「你有团队精神吗?」经理问。
那条狗掉头看了看门外,一大群野狗在外面虎视耽耽。
「我真的不能雇狗做这份工作。」经理气急败坏地说。
「就算会编程、有团队精神,但是我需要的雇员至少要能精通两种语言。」
那条狗抬头看着经理说:「喵-噢。」
---------------------------------
原创文章 By
android和动画
---------------------------------