1. 程式人生 > >利用屬性動畫Animator實現的一個小demo,

利用屬性動畫Animator實現的一個小demo,

這個demo只用到了

AnimatorSet和ObjectAnimator:
ObjectAnimator的作用是:對某一個屬性進行精確的控制.
AnimatorSet的作用是對ObjectAnimator設定的屬性進行綜合控制,如同時進行,或者精確的控制誰先進行誰後進行等
這裡要細說一下ObjectAnimator: 
 /** 說明:
                 * ObjectAnimator的大部分方法中,如ofFloat(),ifInt(),ofObject()等方法裡有兩個引數,第一個引數
                 * Object 型別的target,為執行動畫的控制元件,這裡為imageView,官方的解釋為This object should have a
                 * public method on it called setName(), 意思是這個引數物件只要有setXxx()的方法就可以,
                 * 第二個引數為String 型別的propertyName引數,官方對這個引數的解釋為where name is the value
                 * of the propertyName parameter,這個的定語where指的就是上一句的setName()方法,
                 * 意思是第二個引數的值為第一個引數的setXxx()方法中的Xxx,以imageView為例:imageView有很多set方法,
                 * 如setBackground();setX();setY();setTranslationX();setTranslationY();setScaleX();
                 * setScaleY();setRotationX();setRotationY();setPivotX();setPivotY();setAlpha()等等,
                 * 那麼第二個引數的值就可以為Background,X,Y,TranslationX,TranslationY;ScaleX,ScaleY,
                 * RotationX,RotationY,PivotX,PivotY,Alpha等,引數值大小寫均可.大多數情況下我們用到的值為
                 * 以下幾個:
                 * X                     x軸最終位置
                 * Y                     y軸最終位置
                 * alpha                 透明度
                 * rotation              z軸旋轉(平面效果)
                 * rotationX             x軸翻轉(3D效果)
                 * rotationY             y軸翻轉(3D效果)
                 * translationX          x水平偏移(平面效果)
                 * translationY          y水平偏移(平面效果)
                 * ScaleX                (注意為)Y軸縮放(3D效果)
                 * ScaleY                (注意為)X軸縮放(3D效果)
                 */
對animator.setInterpolator(TimeInterpolator value)方法的引數再作一下說明:
    animator.setInterpolator(TimeInterpolator value)方法的引數有如下幾個常用值可以設定:
                   *
                   * new BounceInterpolator()                 自由落體的效果(到達指定距離回彈幾下)
                   * new AccelerateDecelerateInterpolator()   先慢後快再慢(系統預設)
                   * new AccelerateInterpolator()             由慢變快
* new AnticipateInterpolator() 先緩慢往指定方向的反方向移,再加速往指定方向移
* new AnticipateOvershootInterpolator() 先緩慢往指定方向的反方向移,再加速往指定方向移,再緩慢往指 定方向的反方向移
* new DecelerateInterpolator() 由快變慢
* new FastOutLinearInInterpolator() 快速勻速運動
* new FastOutSlowInInterpolator() 先慢後快再慢
* new LinearInterpolator() 緩慢勻速移動
* new LinearOutSlowInInterpolator() 先極快後慢
* new OvershootInterpolator() 快速運動超出指定距離後緩慢返回
*
*/
需要用到的主要的知識介紹完畢,下面上程式碼:
package com.example.administrator.animatorandanimation;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.BounceInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.Toast;

public class SecondActivity extends AppCompatActivity implements View.OnClickListener {
    private ImageView image, btn_01, btn_02, btn_03, btn_04;
    private boolean flag = true;//用來判斷按鈕點選狀態

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

        initView();
        initEvent();
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.image:
                if (flag) {
                    AnimatorSet set = new AnimatorSet();
                    ObjectAnimator animator01 = ObjectAnimator.ofFloat(btn_01, "TranslationX", -140f, 0f);
                    ObjectAnimator animator02 = ObjectAnimator.ofFloat(btn_02, "TranslationX", 140f, 0f);
                    ObjectAnimator animator03 = ObjectAnimator.ofFloat(btn_03, "TranslationY", -140f, 0f);
                    ObjectAnimator animator04 = ObjectAnimator.ofFloat(btn_04, "TranslationY", 140f, 0f);

                    animator01.setInterpolator(new BounceInterpolator());//設定為自由落體運動
                    animator02.setInterpolator(new BounceInterpolator());
                    animator03.setInterpolator(new BounceInterpolator());
                    animator04.setInterpolator(new BounceInterpolator());

                    viewStateVisible();//設定控制元件可見
                    set.playTogether(animator01, animator02, animator03, animator04);//讓動畫效果同時實現
                    set.setDuration(500);//動畫持續時間
                    set.start();//開啟動畫
                    flag = false;//把標誌置為false,用於回收彈出去的控制元件
                }
                else {
                    AnimatorSet set = new AnimatorSet();
                    ObjectAnimator animator01 = ObjectAnimator.ofFloat(btn_01, "TranslationX", 0f, -140f);
                    ObjectAnimator animator02 = ObjectAnimator.ofFloat(btn_02, "TranslationX", 0f, 140f);
                    ObjectAnimator animator03 = ObjectAnimator.ofFloat(btn_03, "TranslationY", 0f, -140f);
                    ObjectAnimator animator04 = ObjectAnimator.ofFloat(btn_04, "TranslationY", 0f, 140f);

                    animator01.setInterpolator(new LinearInterpolator());//設定為緩慢勻速直線運動
                    animator02.setInterpolator(new LinearInterpolator());
                    animator03.setInterpolator(new LinearInterpolator());
                    animator04.setInterpolator(new LinearInterpolator());

                    set.playTogether(animator01, animator02, animator03, animator04);
                    set.setDuration(500);
                    set.start();
                    //設定一個延時,作用就是當再次點選按鈕回收這些控制元件時,不會立刻消失,而是會延時250ms在消失
                    Handler handler = new Handler();
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            viewStateGone();
                        }
                    }, 250);
                    flag = true;//把標誌置為true,用於再次釋放控制元件
                }
                break;
            case R.id.btn_01:
                Toast.makeText(this, "btn_01", Toast.LENGTH_SHORT).show();
                //viewStateGone();
                break;
            case R.id.btn_02:
                Toast.makeText(this, "btn_02", Toast.LENGTH_SHORT).show();
                //viewStateGone();
                break;
            case R.id.btn_03:
                Toast.makeText(this, "btn_03", Toast.LENGTH_SHORT).show();
                //viewStateGone();
                break;
            case R.id.btn_04:
                Toast.makeText(this, "btn_04", Toast.LENGTH_SHORT).show();
                //viewStateGone();
                break;
        }

    }

    private void initView() {
        image = (ImageView) findViewById(R.id.image);
        btn_01 = (ImageView) findViewById(R.id.btn_01);
        btn_02 = (ImageView) findViewById(R.id.btn_02);
        btn_03 = (ImageView) findViewById(R.id.btn_03);
        btn_04 = (ImageView) findViewById(R.id.btn_04);
    }

    private void initEvent() {
        image.setOnClickListener(this);
        btn_01.setOnClickListener(this);
        btn_02.setOnClickListener(this);
        btn_03.setOnClickListener(this);
        btn_04.setOnClickListener(this);
    }

    //view的狀態為不可見
    public void viewStateGone() {
        btn_01.setVisibility(View.GONE);
        btn_02.setVisibility(View.GONE);
        btn_03.setVisibility(View.GONE);
        btn_04.setVisibility(View.GONE);

    }

    //view的狀態為可見
    public void viewStateVisible() {
        btn_01.setVisibility(View.VISIBLE);
        btn_02.setVisibility(View.VISIBLE);
        btn_03.setVisibility(View.VISIBLE);
        btn_04.setVisibility(View.VISIBLE);
    }
}
對應的佈局檔案:
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    >

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/button_shape"/>

    <ImageView
        android:id="@+id/btn_01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/btn_01"
        android:layout_centerInParent="true"
        android:layout_alignLeft="@+id/image"
        android:layout_marginLeft="140dp"
        android:visibility="gone"
        />

    <ImageView
        android:id="@+id/btn_02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/btn_02"
        android:layout_centerInParent="true"
        android:layout_alignRight="@+id/image"
        android:layout_marginRight="140dp"
        android:visibility="gone"
        />

    <ImageView
        android:id="@+id/btn_03"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/btn_03"
        android:layout_centerInParent="true"
        android:layout_alignTop="@+id/image"
        android:layout_marginTop="140dp"
        android:visibility="gone"
        />

    <ImageView
        android:id="@+id/btn_04"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/btn_04"
        android:layout_centerInParent="true"
        android:layout_alignBottom="@+id/image"
        android:layout_marginBottom="140dp"
        android:visibility="gone"
        />


</RelativeLayout>
中間的imageView用到了自定義控制元件,控制元件樣子是一個圓形,下面是自定義控制元件的程式碼:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
   <!--先畫一個白色的大圓,再畫一個紅色的小圓,然後用紅色小圓覆蓋白色的大圓,就形成這種效果-->
    <item>
        <shape android:shape="oval">
            <corners android:radius="90dp"/>
            <solid android:color="@android:color/white"/>
            <size
                android:width="100dp"
                android:height="100dp"/>
        </shape>
    </item>

    <item
        android:bottom="8dp"
        android:right="8dp"
        android:top="8dp"
        android:left="8dp">
        <!--當按鈕被點選時,顏色為深紅色-->
        <selector xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:state_pressed="true">
                <shape android:shape="oval">
                    <corners android:radius="90dp"/>
                    <solid android:color="#e66b4f"/>
                    <size
                        android:width="92dp"
                        android:height="92dp"/>
                </shape>
            </item>
        <!--當按鈕未被點選時,顏色為淺紅色-->
            <item>
                <shape android:shape="oval">
                    <corners android:radius="90dp"/>
                    <solid android:color="#f3876f"/>
                    <size
                        android:width="92dp"
                        android:height="92dp"/>
                </shape>
            </item>
        </selector>
    </item>

</layer-list>

下面是效果圖:

以上四張圖片自左向右再向下依次為:初始效果,點選紅色按鈕彈出選單(向外彈出時有自由落體效果)效果,點選彈出按鈕效果,再次點選紅色回收選單效果