昨天技术群里有个朋友,在做动画时出现了问题。帮他解决问题的同时,有些基础代码好久不写有点忘记了。所以今天 来简单复习一下。先上gif。
先简单将代码及项目贴出来,完成项目在https://download.csdn.net/download/qq_36467463/10908701下载。
还要加一些难点的动画,等有时间了将项目传上来。
public class MainActivity extends AppCompatActivity {
private ImageView attributeIv;
private TextView attributeTv;
private ImageView frameIv;
private ValueAnimator valueAnimator;
private ObjectAnimator translationY;
private AnimationDrawable animationDrawable;
private Animation patchAnimation;
private ImageView patchIv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
//属性动画
//数字变
attributeTvAnim();
//图形变
attributeIvAnim();
//帧动画
frameAnim();
//补间动画
patchAnim();
}
/**
* 补间动画
*/
private void patchAnim() {
//补间动画有translate,scale,rotate,alpha
//
patchAnimation = AnimationUtils.loadAnimation(this, R.anim.anim_earth_big_x);
}
/**
* 帧动画
*/
private void frameAnim() {
//如果帧动画的图片太多了就容易OOM。如:一般情况下5张没问题,20张就不太好了
//frameIv.setImageDrawable(getResources().getDrawable(R.drawable.anim_earth_load_color));
animationDrawable = (AnimationDrawable) frameIv.getDrawable();
}
/**
* 属性动画
* 图形变
*/
private void attributeIvAnim() {
//propertyName变化的类型。其余还有alpha,rotation,translationX等
//此处为上下的平移,从attributeIv原来的位置,移100的距离(下为正,上为负)。同理可多次移动
translationY = ObjectAnimator.ofFloat(attributeIv, "translationY", attributeIv.getTranslationY(), 100f);
translationY.setDuration(5000);
//其余的方法参照valueAnimator都差不多
}
/**
* 属性动画
* 数字变
*/
private void attributeTvAnim() {
//从1到3
valueAnimator = ValueAnimator.ofFloat(1, 3);
//从1到3,在从3到10(在从10变5方法以此类推)
//ValueAnimator valueAnimator = ValueAnimator.ofFloat(1, 3,10);
//设置时长
valueAnimator.setDuration(2000);
//设置延长多久后开始
valueAnimator.setStartDelay(500);
//设置循环次数,Animation.INFINITE为无限
valueAnimator.setRepeatCount(0);
//监听
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//根据差值器没变动一次就调用一下
float value= (float) animation.getAnimatedValue();
Log.i("Anim","-------valueAnimator--------"+value);
attributeTv.setText(value+"");
//请求从新布局
//attributeTv.requestLayout();
}
});
}
private void initView() {
attributeIv = findViewById(R.id.anim_main_attribute_iv);
attributeTv = findViewById(R.id.anim_main_attribute_tv);
frameIv = findViewById(R.id.anim_mian_frame_iv);
patchIv = findViewById(R.id.anim_mian_patch_iv);
}
/**
* 动画开始按钮
* @param v
*/
public void animClick(View v){
if(valueAnimator!=null&&!valueAnimator.isRunning()){
valueAnimator.start();
}
if(translationY!=null&&!translationY.isRunning()){
translationY.start();
}
if(animationDrawable!=null&&!animationDrawable.isRunning()){
animationDrawable.start();
}
if(patchAnimation!=null){
patchIv.startAnimation(patchAnimation);
}
}
@Override
protected void onStop() {
super.onStop();
//将动画关闭释放
if(animationDrawable!=null&&!animationDrawable.isRunning()){
animationDrawable.stop();
}
}
/**
* 属性动画图标按钮
* @param v
*/
public void attributeIvClick(View v){
Toast.makeText(this,"属性动画,焦点随控件走。" +
"\n补间动画,控件的焦点始终在初始的位置",Toast.LENGTH_SHORT).show();
}
}
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<!--oneshot中false为循环,true为一次-->
<item android:drawable="@drawable/anim_frame_1" android:duration="500"/>
<item android:drawable="@drawable/anim_frame_2" android:duration="500"/>
<item android:drawable="@drawable/anim_frame_3" android:duration="500"/>
<item android:drawable="@drawable/anim_frame_4" android:duration="500"/>
<item android:drawable="@drawable/anim_frame_5" android:duration="1000"/>
</animation-list>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000">
<scale
android:fromXScale="1"
android:fromYScale="1"
android:toXScale="1.2"
android:toYScale="1.2"
/>
<translate
android:fromYDelta="0"
android:fromXDelta="0"
android:toXDelta="200"
android:toYDelta="0"
/>
</set>