天天看點

Android屬性動畫應用——菜單以散開的方式彈出

一、前言

Google推出的新方法——android屬性動畫,讓很多大牛和熱愛技術的人高興不已,紛紛發表自己的學習心得、認識以及教程。這裡,我是通過在慕課網的相關視訊學習中,獲得的啟發,于是整理了一下,希望與大家分享。

OK,廢話不多說,趕快進入主題。

下面先展示一下界面效果:

![點選橘紅色的按個按鈕之後,會彈出五個小按鈕,形成一直角三角形。如果想讓它展示扇形或者其他形狀的效果的話,我還沒有嘗試。大家如果有做的話,記得@我哈。]

Android屬性動畫應用——菜單以散開的方式彈出

然後,明确一下我們的目的:

我們的目的,是想讓菜單裡的子按鈕依次散布在菜單按鈕的周圍,形成直角。是以,各個子按鈕的Y值應該是依次減小的,而它們的X值則是依次增加,并且這個動畫變化過程是同時進行的。

二、代碼

首先,我們先來看XML檔案。檔案名是activity_main.

<FrameLayout
    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=".MainActivity">

   <ImageView
       android:id="@+id/img_b"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:padding="20dp"
       android:src="@drawable/presence_away"/>

    <ImageView
        android:id="@+id/img_c"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:src="@drawable/presence_audio_online"/>
    <ImageView
        android:id="@+id/img_d"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:src="@drawable/presence_busy"/>
    <ImageView
        android:id="@+id/img_e"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:src="@drawable/presence_online"/>
    <ImageView
        android:id="@+id/img_a"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:src="@drawable/ic_menu_add"/>
</FrameLayout>
           

内容很簡單,一個framlayout布局,然後,将所有的子按鈕和菜單按鈕疊放在一起。需要注意的是,要将最後顯示的圖檔(也就是所謂的菜單按鈕)放在最上面。

然後,咱們再來看一下MainActivity.java。(後面會做解釋)

package com.example.myapplication;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity implements View.OnClickListener{
//數組存放圖檔ID,通過list進行圖檔周遊
    private int[] res = {R.id.img_a,R.id.img_b,
                    R.id.img_c,R.id.img_d,R.id.img_e};
    private List<ImageView> list_img = 
                       new ArrayList<ImageView>();
/*
 1.  flag為true,當點選按鈕的時候,彈出菜單
 2.  flag為false,當點選按鈕的時候,收回菜單
*/                       
    private boolean flag = true;

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

        for(int i=;i<res.length;i++){
            ImageView img = (ImageView)  
                                   findViewById(res[i]);
            img.setOnClickListener(this);
            list_img.add(img);
        }
    }
    @Override
    public void onClick(View view){
        switch (view.getId()){
            case R.id.img_a:
                if(flag){
                    startAnim();  //彈出菜單動畫
                }else{
                    closeAnim();  //收回菜單動畫
                }
                break;
            default:
//這裡隻是簡單的對彈出按鈕的點選響應進行了處理,具體應用時可以進行完善 
  Toast.makeText(MainActivity.this,"click"+view.getId(),
                              Toast.LENGTH_SHORT).show();
                break;
        }
    }

    private void closeAnim(){
        for(int i =;i<res.length;i++){
//給出一個沿Y軸移動的動畫
    ObjectAnimator animator = ObjectAnimator.ofFloat(
list_img.get(i),"translationY",(res.length-i-)*f,f );
//給出一個沿X軸移動的動畫 
    ObjectAnimator animator1 = ObjectAnimator.ofFloat(
    list_img.get(i),"translationX",(i-)*f,f );
    //定義屬性動畫集合的對象
            AnimatorSet animSet = new AnimatorSet();
    //通過with方法,讓兩個動畫同時進行
            animSet.play(animator).with(animator1);
    //設定延遲時間,讓菜單内容相繼彈出
            animSet.setStartDelay();
            animSet.start();
    //然後,設定flag為true,當再次點選的時候,收回菜單
            flag = true;
        }
    }
 //兩種方法的内容大體相同,隻是動畫屬性的參數相反
    private void startAnim() {
        for(int i =;i<res.length;i++){
       ObjectAnimator animator = ObjectAnimator.ofFloat(
       list_img.get(i),"translationY",  
                              f,(res.length-i-)*f );
       ObjectAnimator animator1 = ObjectAnimator.ofFloat(
    list_img.get(i),"translationX", f , (i-)*f );
            AnimatorSet animSet = new AnimatorSet();
            animSet.play(animator).with(animator1);
            animSet.setStartDelay();
            animSet.start();
            flag = false;
        }
    }
}
           

三、說明

對照上面的代碼,進行下面的一些解釋:

1、這裡解釋一下ObjectAnimator對象的參數的含義:

ObjectAnimator animator = ObjectAnimator.ofFloat(

list_img.get(i),”translationY”,

0f,(res.length-i-1)*50f );

第一個是object對象,添加的是我們所要賦予動畫效果的對象,

如我們的list_img.get(i)

第二個是動畫屬性,也就是我們想要的動畫效果

之後的就是設定動畫屬性的參數,跟animation動畫參數設定一樣。

2、下面說明一下動畫屬性的參數設定:

再來明确一下我們的目的:我們的目的,是想讓菜單裡的子按鈕依次散布在菜單按鈕的周圍,形成直角。是以,各個子按鈕的Y值應該是依次減小的,而它們的X值則是依次增加,并且這個動畫變化過程是同時進行的。 好,下面,我們借助list來進行參數設定。

對于”translationY”,我們讓它從Y=0 的地方,依次往外彈出(res.length-i-1)*50f 的距離。50F是我們設定的各個子按鈕之間Y軸的距離。i則代表我們加載的圖檔資源的序号。這裡要注意!我們的i是從1開始的。也就是讓菜單按鈕保持不動,是以,為了讓最後一個子按鈕的Y值為零,也就是跟螢幕上端平行,我們還要再減一,即我們的乘數因子為(res.length-i-1)。當i=1的時候,第一個子按鈕的Y值最大,距離螢幕上端最遠,然後,随着i值的增大,子按鈕的Y值逐漸減小,距離螢幕上端也越來越近。

同理,對于”translationX”,則是從X=0的地方,依次彈出(i-1)*50f的距離。

2、closeAnim()方法内容跟startAnim()大體相同,隻是參數設定上略有差別。收回菜單的是,子按鈕的動畫軌迹跟彈出的時候是相反的,是以,我們隻需要把動畫屬性的參數調換一下位置即可。如有疑問,請參考代碼進行對比。

四、附文

1、對屬性動畫不熟悉的小夥伴,給大家推薦郭霖大俠的部落格http://blog.csdn.net/guolin_blog/article/details/43536355

裡面講得很詳細,可以收藏。我不是做廣告的哦,隻是資源分享下。

(^o^)/~

2、還有慕課網原版視訊網址 http://www.imooc.com/learn/263

如果有說得不到位的地方,大家可以去參考。本人也算是剛剛菜鳥進階一點點吧,是以大家如有更好的見解,我們也可以共同探讨、互相學習。同時,說明一下,我這裡用的是android studio。但是不妨礙的,代碼比較少,也很好了解,eclipse也比較容易實作。

3、OK,今天的内容就這些了,有不當的地方,大家多見諒、多溝通,我們共同探讨、互相學習。歡迎大家批評指教~