动画与图形

1、Animations介绍

Android提供了几种动画类型:View Animation、Drawable Animation、Property Animation(属性动画)。ViewAnimation分别是Tween动画和Frame动画。Tween通过场景里的对象不断的进行图片的变换,比如平移、渐变、缩放、旋转等来产生动画效果,Frame动画叫做顺序播放事先做好的图像,和电影类似。

2、Tween动画

有四种:
Alpha:透明渐变动画

Scale:缩放动画,渐变尺寸伸缩动画

Translate:移动动画,画面转换位置移动动画

Rotate:旋转动画

这些动画执行步骤差不多:先定义Animation动画对象,然后设置动画的一些属性,最后通过startAnimation()方法开始动画。

//设置动画显示的时间,durationMills为动画显示时间的长短,以毫秒为单位
setDuration(long durationMills);
//播放动画,animation为要播放的动画
startAnimation(Animation animation)

 

第一种:Alpha

(1)通过XML来创建动画alpha_anim.xml。在res/anim目录下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:duration="5000"
        android:fromAlpha="0.1"
        android:toAlpha="1.0" />
</set>

 

        //加载动画资源文件
        Animation scale = AnimationUtils.loadAnimation(MainActivity.this, R.anim.alpha_anim);
        img.startAnimation(scale);

 

(2)直接在程序中创建动画

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv = (TextView) findViewById(R.id.tv);
        img = (ImageView) findViewById(R.id.img);
        //创建Alpha动画
        Animation alpha = new AlphaAnimation(0.1f, 1.0f);
        //设置动画时间为5s
        alpha.setDuration(5000);
        //开始播放
        img.startAnimation(alpha);
    }
}

 

第二种:.Scale缩放动画

<scale>标签为缩放节点

android:fromXscale="1.0"    表示开始时X轴缩放比例为1.0(原图大小*1.0为原图大小)

android:toXscale="0.0"       表示结束时X轴缩放比例为0.0(原图大小*0.0为缩小到看不见)

android:fromYscale="1.0"   (与X轴类似)

android:toYscale="0.0"       (与X轴类似)

android:pivotX="50%"        X轴所放的位置为中心点

android:pivotY="50%"         Y轴缩放的位置为中心点

android:duration="2000"      动画播放时间,这里是2000毫秒,也就是2秒

 

这个动画布局设置动画从大到小进行缩小

文件夹anim下

little.xml

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
                android:fromXScale="1.0" 
                    android:toXScale="0.0"
                android:fromYScale="1.0" 
                android:toYScale="0.0" 
                android:pivotX="50%"
                android:pivotY="50%" 
                android:duration="2000">
</scale>

big.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
     <scale        
       android:fromXScale="1.0"
       android:toXScale="2.0"
       android:fromYScale="1.0"
       android:toYScale="2.0"
       android:pivotX="50%"
       android:pivotY="50%"
       android:duration="2000"
       /> 

</set>

activity_main.xml

<LinearLayout 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:orientation="vertical"
     >
   
    <Button 
        android:id="@+id/btn0"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="放大"
        />

    <Button 
        android:id="@+id/btn1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="缩小"
        />
    <ImageView 
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher"        
        />
</LinearLayout>

MainActivity.java:

public class MainActivity extends Activity {

    Button but0;
    Button but1;
    ImageView img;
    Animation liAnimation;
    Animation bigAnimation;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        img=(ImageView) findViewById(R.id.img);
        
        liAnimation=AnimationUtils.loadAnimation(this, R.anim.little);
        bigAnimation=AnimationUtils.loadAnimation(this, R.anim.big);
        
        but0=(Button) findViewById(R.id.btn0);
        but1=(Button) findViewById(R.id.btn1);
        
        but0.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View arg0) {
                img.startAnimation(bigAnimation);
                
            }
        });
        but1.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View arg0) {
                img.startAnimation(liAnimation);
                
            }
        });
        
    }
   
}

 

 

 第三种:Rotate旋转动画

<rotate>标签为旋转节点

Tween一共为我们提供了3种动画渲染模式

android:interpolator="@android:anim/accelerate_interpolator"

设置动画渲染器为加速动画(播放越来越快)

android:interpolator="@android:anim/decelerate_interpolator"

设置动画渲染器为减速动画(播放越来越慢)

android:interpolator="@android:anim/accelerate_decelerate_interpolator"

设置动画渲染器为先加速再减速(开始速度最快,逐渐变慢)

android:fromDegrees="+360"设置动画开始的角度

android :toDegrees="0" 设置动画结束的角度

 

这个动画布局设置动画将向左做360度旋转加速运动

android:interpolator="@android:anim/acclerate_interpolator"
android:fromDegrees="+360"
android:toDegrees="0"  
android:pivotX="50%"  
android:pivotY="50%"  
android:duration="2000" 

youx.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate 
        android:interpolator="@android:anim/accelerate_interpolator"
        android:fromDegrees="-360"
        android:toDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="2000"
        />

</set>

zuox.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate 
        android:interpolator="@android:anim/accelerate_interpolator"
        android:fromDegrees="+360"
        android:toDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="2000"
        />

</set>

 

zuox=AnimationUtils.loadAnimation(this, R.anim.zuox);
youx=AnimationUtils.loadAnimation(this, R.anim.youx); 
btn2=(Button) findViewById(R.id.btn2);
btn3=(Button) findViewById(R.id.btn3);
btn2.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View arg0) {
                img.startAnimation(zuox);
                
            }
        });
        btn3.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View arg0) {
                img.startAnimation(youx);
                
            }
        });

 

第四种:Translate

<translate>标签为移动节点

android:repeatCount="infinite"

设置动画为循环播放,这里可以写具体的int数值,设置动画播放几次,但是他记录的次数是从0开始数的。

整值型:

fromXDelta属性为动画起始时X坐标上的位置

fromYDelta属性为动画起始时Y坐标上的位置

toXDelta属性为动画结束时X坐标上的位置

toYDelta属性为动画结束时Y坐标上的位置

这些属性里还可以加上%和p,例如:

android:toXDelta="80%"表示父层view的80%,shiyitafucengview为参照的。

trany.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0"
        android:toXDelta="320"
        android:fromYDelta="0"
        android:toYDelta="120"
        android:duration="2000"
        android:repeatCount="infinite"
        ></translate>

</set>

MainActivity.java

trany=AnimationUtils.loadAnimation(this, R.anim.trany);
btn4=(Button) findViewById(R.id.btn4);
btn4.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View arg0) {
                img.startAnimation(trany);
                
            }
        });

 

 

3、用AnimationDrable实现Frame动画

首先在res资源文件夹下新建anim动画文件夹,在这个文件夹中建立一个animation.xml的文件

建立一个<animation-list>

 <animation-list xmlns:android="http://schemas.android.com/apk/res/android" 
android:oneshot="false"> <item android:drawable="@drawable/a" android:duration="100" /> <item android:drawable="@drawable/b" android:duration="100" /> <item android:drawable="@drawable/c" android:duration="100" /> <item android:drawable="@drawable/d" android:duration="100" /> <item android:drawable="@drawable/e" android:duration="100" /> <item android:drawable="@drawable/f" android:duration="100" /> <item android:drawable="@drawable/g" android:duration="100" /> <item android:drawable="@drawable/h" android:duration="100" /> <item android:drawable="@drawable/i" android:duration="100" /> <item android:drawable="@drawable/j" android:duration="100" /> </animation-list>

android:oneshot="false"属性,默认false表示动画循环播放,如果是true则表示只播放一次

<item>标签中记录着每一帧的信息

android:drawable="@drawable/a"表示这一帧的图片为a

android:duration="100"表示这一帧持续100毫秒,可以根据这个来调节动画播放的速度。

 AnimationDrawable是来控制帧动画,这个类中提供了很多方法:

animationDrawable.start();                         开始这个动画

animationDrawable.stop();                          结束这个动画

animationDrawable.setAlpha(100);              设置动画的透明度,取值范围(0-255)

animationDrawable.setOneShot(true);           设置单次播放

animationDrawable.setOneShot(false);           设置循环播放

animationDrawable.isRunning();                     判断动画是否正在播放

animationDrawable.getNumberOfFrames();      得到动画的帧数

 

 animation.xml

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" 
    android:oneshot="false">
    <item android:drawable="@drawable/a" android:duration="100"/>
    <item android:drawable="@drawable/b" android:duration="100"/>
    <item android:drawable="@drawable/c" android:duration="100"/>
    <item android:drawable="@drawable/d" android:duration="100"/>
    <item android:drawable="@drawable/e" android:duration="100"/>

</animation-list>

activity_main.xml

<LinearLayout 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:orientation="vertical"
    >

    <Button 
        android:id="@+id/btn0"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="播放动画"
        />
    <Button 
        android:id="@+id/btn1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="停止动画"
        />
    
    <RadioGroup 
        android:id="@+id/radio0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        <RadioButton 
            android:id="@+id/radiobut0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="单次播放"
            />
        <RadioButton 
            android:id="@+id/radiobut1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="循环播放"
            />
    </RadioGroup>
    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="拖动进度条修改透明度(0-255)之间"
        />
    <SeekBar 
        android:id="@+id/seekbar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:max="256"
        android:progress="256"
        />
    <ImageView 
        android:id="@+id/img"
        android:background="@anim/animation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        />

</LinearLayout>

最后这个ImageView是用来显示动画的。android:background="@anim/animation"设置这个ImageView显示的背景为一个动画,动画资源的路径为res/anim/animation.xml

MainActivity.java

public class MainActivity extends Activity {

    Button btn0;
    Button btn1;
    RadioGroup radio0;
    RadioButton rbut0;
    RadioButton rbut1;
    SeekBar seekbar;
    ImageView img;
    AnimationDrawable animationDrawable;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        img=(ImageView) findViewById(R.id.img);
        //拿到ImageView对象
        animationDrawable=(AnimationDrawable) img.getBackground();
        //通过ImageView对象拿到背景显示的AnimationDrawable


        btn0=(Button) findViewById(R.id.btn0);
        btn0.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View arg0) {
                if(!animationDrawable.isRunning()){
                    //播放动画
                    animationDrawable.start();
                }                
            }
        });
        
        btn1=(Button) findViewById(R.id.btn1);
        btn1.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                //停止动画
                if(animationDrawable.isRunning()){
                    animationDrawable.stop();
                }                
            }
        });
        
        radio0=(RadioGroup) findViewById(R.id.radio0);
        rbut0=(RadioButton) findViewById(R.id.radiobut0);
        rbut1=(RadioButton) findViewById(R.id.radiobut1);
        radio0.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                if(checkedId==rbut0.getId()){
                    //设置单次播放
                    animationDrawable.setOneShot(true);
                }else if(checkedId==rbut1.getId()){
                    //设置循环播放
                    animationDrawable.setOneShot(false);
                }
                //发生改变后让动画重新播放
                animationDrawable.stop();
                animationDrawable.start();
            }
        });
        
        seekbar=(SeekBar) findViewById(R.id.seekbar);
        //监听进度条修改透明度
        seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {     
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {                             
            }            
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {               
            }         
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                    boolean fromUser) {
                animationDrawable.setAlpha(progress);
                //设置动画Alpha值
                img.postInvalidate();
                //通知img刷新屏幕
                
            }
        });
    }    
}

 

拖动进度条设置Alpha值的时候一定要使用img.postInvalidate();方法来通知UI线程重绘屏幕中的img,否则会看不到透明的效果。

 5、属性动画

    public void ImgClick(View view) {
        //单个动画效果
//        ObjectAnimator.ofFloat(view, "rotationX", 0.0f, 360f).setDuration(500).start();

        //组合多个动画
        PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("alpha", 1f, 0f, 1f);
        PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0f, 1f);
        PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0f, 1f);
        ObjectAnimator.ofPropertyValuesHolder(view, p1, p2, p3).setDuration(500).start();

    }

 

    //自由落体示例
    public void Imgclick(final View view) {
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        //定义一个动画
        ValueAnimator va = ValueAnimator.ofFloat(view.getY(), dm.heightPixels).setDuration(500);
        //监听动画的每一个动作
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                view.setTranslationY((Float) valueAnimator.getAnimatedValue());
            }
        });
        va.start();
    }

 

监听动画的事件:

对于动画,一般都是一些辅助效果,比如要删除某个元素,可能希望十个淡出的效果,但是最终还是要删掉,并不是透明度没了,还站着位置,所以我们需要知道动画如何结束。

 

posted @ 2015-08-26 10:53  ChHM  阅读(270)  评论(0编辑  收藏  举报