Android动画属性一

来源:互联网 发布:dede整站源码 编辑:程序博客网 时间:2024/05/19 17:07

Android动画属性一

标签: Android 动画属性


  • Android动画属性一
  • 控件添加动画属性
  • ObjectAnimator 动画效果
    • 1ofFloat实现旋转
    • 2实现缩放和淡出
      • 方法一
      • 方法二
  • 3ValueAnimator属性动画
    • 动画监听
  • 3多动画的运行次序

1. 控件添加动画属性

布局

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:id="@+id/content_layout">    <ImageView        android:id="@+id/image_view"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:src="@drawable/back2"        android:scaleType="centerCrop"        android:onClick="rotateAnimation"/></RelativeLayout>

其中ImageView添加了一个属性 android:onClick="rotateAnimation"
点击时会执行rotateAnimation
rotateAnimation并不是系统给的,是自己实现的。rotateAnimation只是一个名字,要实现这个名字的方法。
如下:

public class ScrollingActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_scrolling);    }    public void rotateAnimation(View view){       //具体动画    }}

2. ObjectAnimator 动画效果

1、ofFloat实现旋转

如下:

public class ScrollingActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_scrolling);    }    public void rotateAnimation(View view){        /**         * rotationX 绕着X轴旋转         * 从初始夹角180度开始旋转到10度         * 最后显示10度的状态         */        ObjectAnimator.ofFloat(view,"rotationX",180.0f,10.0f).setDuration(500).start();    }}

使用了ObjectAnimator动画效果

rotationX 绕着X轴旋转
ofFloat(控件对象,方向,起始角度,终止角度);
或者 ofFloat(控件对象,方向,终止角度);
setDuration(动画持续时间);
start()开始;

对于ObjectAnimator
1、提供了ofInt、ofFloat、ofObject,这几个方法都是设置动画作用的元素、作用的属性、动画开始、结束、以及中间的任意个属性值。
当对于属性值,只设置一个的时候,会认为当然对象该属性的值为开始(getPropName反射获取),然后设置的值为终点。如果设置两个,则一个为开始、一个为结束~~~
动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新某个属性,必须得有getter(设置一个属性值的时候)和setter方法~
2、如果你操作对象的该属性方法里面,比如上例的setRotationX如果内部没有调用view的重绘,则你需要自己按照下面方式手动调用。

anim.addUpdateListener(new AnimatorUpdateListener()          {              @Override              public void onAnimationUpdate(ValueAnimator animation)              {  //              view.postInvalidate();  //              view.invalidate();              }          });  

2、实现缩放和淡出

方法一

public void rotateAnimation(final View view){        ObjectAnimator animator = ObjectAnimator.ofFloat(view,"xyz",1.0f,0.0f).setDuration(500);        animator.start();        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                float cVal = (float) animation.getAnimatedValue();                view.setAlpha(cVal);    //设置控件透明度                view.setScaleY(cVal);   //设置控件x轴宽度                view.setScaleX(cVal);   //设置控件Y轴宽度            }        });

这里设置了变化量为“xyz”就是一个没有的量,初始值为1,终值为0,点击时变化。
这样就获得了1-0的渐变量,然后设置监听器,变化更新时:

view.setAlpha(cVal); 设置当前渐变量为当前透明度。
view.setScaleX(cVal); 设置当前渐变量为当前View的宽度。
view.setScaleY(cVal); 设置当前渐变量为当前View的高度。

方法二

使用 propertyValuesHolder 同时设置多个变化属性。

public void propertyValuesHolder(View view)      {          PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,                  0f, 1f);          PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f,                  0, 1f);          PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f,                  0, 1f);          ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY,pvhZ).setDuration(1000).start();      }  

3、ValueAnimator属性动画

先是布局代码:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.valueanimatortest.MainActivity">   <ImageButton       android:layout_width="wrap_content"       android:layout_height="wrap_content"       android:src="@drawable/redball"       android:id="@+id/red_ball"/>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:orientation="horizontal">        <Button            android:id="@+id/line"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:onClick="LineRun"            android:text="垂直"/>        <Button            android:id="@+id/not_line"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:onClick="NotLineRun"            android:text="抛物线"/>    </LinearLayout></RelativeLayout>

一个ImageView是一个红球,两个按键分别实现两种动画。

下面是主活动

public class MainActivity extends Activity {    private ImageView mRedBall;    private int mScreenHeight;    public int getScreenHeight(){        Display mDisplay = getWindowManager().getDefaultDisplay();        Point mPoint = new Point();        mDisplay.getSize(mPoint);        return mPoint.y;    }    public int getScreemWidth(){        Display mDisplay = getWindowManager().getDefaultDisplay();        Point mPoint = new Point();        mDisplay.getSize(mPoint);        return mPoint.x;    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_main);        mRedBall = (ImageView) findViewById(R.id.red_ball);        mScreenHeight = getScreenHeight();    }    public void LineRun(View view){    //设置一个变量,大小从0到屏幕长度        ValueAnimator animator = ValueAnimator.ofFloat(0,mScreenHeight-mRedBall.getHeight());        animator.setTarget(mRedBall);        animator.setDuration(2000);        animator.start();        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {            //不断的改变红球的Y坐标                mRedBall.setTranslationY((Float) animation.getAnimatedValue());            }        });    }    //抛物线运动    public void NotLineRun(View view){        ValueAnimator animator = new ValueAnimator();        animator.setDuration(2000);        //设置初始值        animator.setObjectValues(new PointF(0, 0));        animator.setInterpolator(new LinearInterpolator()); //时间差值 线性变化        //自定义数值如何变化        animator.setEvaluator(new TypeEvaluator<PointF>() {            @Override            public PointF evaluate(float fraction, PointF startValue, PointF endValue) {                float x = 200 * fraction * 3;                float y = 0.5f * 200 * fraction * 3 * fraction * 3;                PointF pointF = new PointF(x, y);                return pointF;            }        });        animator.start();        //监听数值变化,不断改变X,Y坐标        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                PointF pointF = (PointF) animation.getAnimatedValue();                mRedBall.setTranslationX(pointF.x);                mRedBall.setTranslationY(pointF.y);            }        });    }}

animator.setInterpolator(new LinearInterpolator());
setInterpolator表示设置变化速率。LinearInterpolator为匀速效果,Accelerateinterpolator为加速效果、DecelerateInterpolator为减速效果。

这里有几种X的值:
TranslationX 控件坐标(是TranslationX坐标,和X的左标不同)
RotationX 翻转角度(和基点对比)
PivotX 基线(旋转中心的X坐标)
ScaleX 控件宽度
X 控件坐标(应该是布局文件中定义的位置坐标)

动画监听

可以在动画的不同阶段设置监听器。
比如我要删除个元素,我可能希望是个淡出的效果,但是最终还是要删掉,并不是你透明度没有了,还占着位置,所以我们需要知道动画如何结束。

public void fadeOut(View view)      {          ObjectAnimator anim = ObjectAnimator.ofFloat(mBlueBall, "alpha", 0.5f);          anim.addListener(new AnimatorListener()          {              @Override              public void onAnimationStart(Animator animation)              {                  Log.e(TAG, "onAnimationStart");              }              @Override              public void onAnimationRepeat(Animator animation)              {                  // TODO Auto-generated method stub                  Log.e(TAG, "onAnimationRepeat");              }              @Override              public void onAnimationEnd(Animator animation)              {                  Log.e(TAG, "onAnimationEnd");                  ViewGroup parent = (ViewGroup) mBlueBall.getParent();                  if (parent != null)                      parent.removeView(mBlueBall);              }              @Override              public void onAnimationCancel(Animator animation)              {                  // TODO Auto-generated method stub                  Log.e(TAG, "onAnimationCancel");              }          });          anim.start();      }  

3、多动画的运行次序

//多动画一起执行    public void togetherRun(View view)      {          ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall, "scaleX",                  1.0f, 2f);          ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall, "scaleY",                  1.0f, 2f);          AnimatorSet animSet = new AnimatorSet();          animSet.setDuration(2000);          animSet.setInterpolator(new LinearInterpolator());          //两个动画同时执行          animSet.playTogether(anim1, anim2);  //一起执行        animSet.start();      }      public void playWithAfter(View view)      {          float cx = mBlueBall.getX();          ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall, "scaleX",                  1.0f, 2f);          ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall, "scaleY",                  1.0f, 2f);          ObjectAnimator anim3 = ObjectAnimator.ofFloat(mBlueBall,                  "x",  cx ,  0f);          ObjectAnimator anim4 = ObjectAnimator.ofFloat(mBlueBall,                  "x", cx);          /**          * anim1,anim2,anim3同时执行          * anim4接着执行          */          AnimatorSet animSet = new AnimatorSet();          animSet.play(anim1).with(anim2);          animSet.play(anim2).with(anim3);          animSet.play(anim4).after(anim3);          animSet.setDuration(1000);          animSet.start();      }  

第一:使用playTogether两个动画同时执行,当然还有playSequentially依次执行~~
第二:如果我们有一堆动画,如何使用代码控制顺序,比如1,2同时;3在2后面;4在1之前等~就是效果2了
有一点注意:animSet.play().with();也是支持链式编程的,但是不要想着狂点,比如 animSet.play(anim1).with(anim2).before(anim3).before(anim5); 这样是不行的,系统不会根据你写的这一长串来决定先后的顺序,所以按照上面例子的写法,多写几行。

0 0
原创粉丝点击