国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android中編寫屬性動畫PropertyAnimation的進階實例

2019-12-12 06:33:56
字體:
來源:轉載
供稿:網友

0、基礎回顧
PropertyAnimation,屬性動畫,顧名思義就是利用對象的屬性變化形成動畫的效果。屬性動畫的類可以用Animator這個抽象類來表示,通常使用它的子類:AnimatorSet和ValueAnimator,同時ValueAnimator有兩個子類分別是ObjectAniamtor和TimeAnimator。
定義屬性動畫的XML資源的時候通常可以是如下三個元素之一作為根元素:
<set>元素:該資源元素代表的是AniamtorSet類,這個類可以包含<set>,<objectAniamtor>,<animator>三個子元素。
<objectAnimator>元素:用于定義objectAniamtor類。
<animator>元素:用于定義ValueAnimator類。
比如說這里一個資源文件的定義如下:

<set android:ordering="[together|sequentially]">   <objectAnimator       android:propertyName="string"      android:duration="int"      android:valueFrom="float|int|color"      android:valueTo="float|int|color"      android:startOffset="int"      android:repeatCount="int"      android:interpolator=""      android:repeatMode="[reapeat|reverse]"      android:valueType="[intType|floatType]"/>    <animator             android:duration="int"      android:valueFrom="float|int|color"      android:valueTo="float|int|color"      android:startOffset="int"      android:repeatCount="int"      android:interpolator=""      android:repeatMode="[reapeat|reverse]"      android:valueType="[intType|floatType]"/>   <set>    ....  </set> </set>

屬性文件通常保存在animator文件夾下面。

1、如何使用xml文件來創建屬性動畫
大家肯定都清楚,View Animator 、Drawable Animator都可以在anim文件夾下創建動畫,然后在程序中使用,甚至在Theme中設置為屬性值。當然了,屬性動畫其實也可以在文件中聲明:
首先在res下建立animator文件夾,然后建立res/animator/scalex.xml

<?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"   android:duration="1000"   android:propertyName="scaleX"   android:valueFrom="1.0"   android:valueTo="2.0"   android:valueType="floatType" > </objectAnimator> 

代碼:

public void scaleX(View view)   {     // 加載動畫     Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scalex);     anim.setTarget(mMv);     anim.start();   } 

使用AnimatorInflater加載動畫的資源文件,然后設置目標,就ok~~是不是很簡單,這只是單純橫向的放大一倍~
如果我希望縱向與橫向同時縮放呢?則可以怎么定義屬性文件:

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"   android:ordering="together" >    <objectAnimator     android:duration="1000"     android:propertyName="scaleX"     android:valueFrom="1"     android:valueTo="0.5" >   </objectAnimator>   <objectAnimator     android:duration="1000"     android:propertyName="scaleY"     android:valueFrom="1"     android:valueTo="0.5" >   </objectAnimator>  </set> 

使用set標簽,有一個orderring屬性設置為together,【還有另一個值:sequentially(表示一個接一個執行)】。
上篇博客中忽略了一個效果,就是縮放、反轉等都有中心點或者軸,默認中心縮放,和中間對稱線為反轉線,所以我決定這個橫向,縱向縮小以左上角為中心點:
代碼:

// 加載動畫     Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);     mMv.setPivotX(0);     mMv.setPivotY(0);     //顯示的調用invalidate     mMv.invalidate();     anim.setTarget(mMv);     anim.start(); 

很簡單,直接給View設置pivotX和pivotY,然后調用一下invalidate,就ok了。
下面看效果圖:

2016419145721361.gif (733×398)

好了,通過寫xml聲明動畫,使用set嵌套set,結合orderring屬性,也基本可以實現任何動畫~~上面也演示了pivot的設置。

2、布局動畫(Layout Animations)
主要使用LayoutTransition為布局的容器設置動畫,當容器中的視圖層次發生變化時存在過渡的動畫效果。
基本代碼為:

LayoutTransition transition = new LayoutTransition();   transition.setAnimator(LayoutTransition.CHANGE_APPEARING,       transition.getAnimator(LayoutTransition.CHANGE_APPEARING));   transition.setAnimator(LayoutTransition.APPEARING,       null);   transition.setAnimator(LayoutTransition.DISAPPEARING,       null);   transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,       null);   mGridLayout.setLayoutTransition(transition); 

過渡的類型一共有四種:
(1)LayoutTransition.APPEARING 當一個View在ViewGroup中出現時,對此View設置的動畫
(2)LayoutTransition.CHANGE_APPEARING 當一個View在ViewGroup中出現時,對此View對其他View位置造成影響,對其他View設置的動畫
(3)LayoutTransition.DISAPPEARING  當一個View在ViewGroup中消失時,對此View設置的動畫
(4)LayoutTransition.CHANGE_DISAPPEARING 當一個View在ViewGroup中消失時,對此View對其他View位置造成影響,對其他View設置的動畫
(5)LayoutTransition.CHANGE 不是由于View出現或消失造成對其他View位置造成影響,然后對其他View設置的動畫。
注意動畫到底設置在誰身上,此View還是其他View。
好了下面看一個綜合的例子:
布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   xmlns:tools="http://schemas.android.com/tools"   android:id="@+id/id_container"   android:layout_width="match_parent"   android:layout_height="match_parent"   android:orientation="vertical" >    <Button     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:onClick="addBtn"     android:text="addBtns" />    <CheckBox     android:id="@+id/id_appear"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:checked="true"     android:text="APPEARING" />    <CheckBox     android:id="@+id/id_change_appear"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:checked="true"     android:text="CHANGE_APPEARING" />    <CheckBox     android:id="@+id/id_disappear"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:checked="true"     android:text="DISAPPEARING" />    <CheckBox      android:id="@+id/id_change_disappear"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:checked="true"     android:text="CHANGE_DISAPPEARING " />  </LinearLayout> 

代碼:

package com.example.zhy_property_animation;  import android.animation.LayoutTransition; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.GridLayout;  public class LayoutAnimaActivity extends Activity implements     OnCheckedChangeListener {   private ViewGroup viewGroup;   private GridLayout mGridLayout;   private int mVal;   private LayoutTransition mTransition;    private CheckBox mAppear, mChangeAppear, mDisAppear, mChangeDisAppear;    @Override   public void onCreate(Bundle savedInstanceState)   {     super.onCreate(savedInstanceState);     setContentView(R.layout.layout_animator);     viewGroup = (ViewGroup) findViewById(R.id.id_container);      mAppear = (CheckBox) findViewById(R.id.id_appear);     mChangeAppear = (CheckBox) findViewById(R.id.id_change_appear);     mDisAppear = (CheckBox) findViewById(R.id.id_disappear);     mChangeDisAppear = (CheckBox) findViewById(R.id.id_change_disappear);      mAppear.setOnCheckedChangeListener(this);     mChangeAppear.setOnCheckedChangeListener(this);     mDisAppear.setOnCheckedChangeListener(this);     mChangeDisAppear.setOnCheckedChangeListener(this);      // 創建一個GridLayout     mGridLayout = new GridLayout(this);     // 設置每列5個按鈕     mGridLayout.setColumnCount(5);     // 添加到布局中     viewGroup.addView(mGridLayout);     //默認動畫全部開啟     mTransition = new LayoutTransition();     mGridLayout.setLayoutTransition(mTransition);    }    /**    * 添加按鈕    *    * @param view    */   public void addBtn(View view)   {     final Button button = new Button(this);     button.setText((++mVal) + "");     mGridLayout.addView(button, Math.min(1, mGridLayout.getChildCount()));     button.setOnClickListener(new OnClickListener()     {        @Override       public void onClick(View v)       {         mGridLayout.removeView(button);       }     });   }    @Override   public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)   {     mTransition = new LayoutTransition();     mTransition.setAnimator(         LayoutTransition.APPEARING,         (mAppear.isChecked() ? mTransition             .getAnimator(LayoutTransition.APPEARING) : null));     mTransition         .setAnimator(             LayoutTransition.CHANGE_APPEARING,             (mChangeAppear.isChecked() ? mTransition                 .getAnimator(LayoutTransition.CHANGE_APPEARING)                 : null));     mTransition.setAnimator(         LayoutTransition.DISAPPEARING,         (mDisAppear.isChecked() ? mTransition             .getAnimator(LayoutTransition.DISAPPEARING) : null));     mTransition.setAnimator(         LayoutTransition.CHANGE_DISAPPEARING,         (mChangeDisAppear.isChecked() ? mTransition             .getAnimator(LayoutTransition.CHANGE_DISAPPEARING)             : null));     mGridLayout.setLayoutTransition(mTransition);   } } 

效果圖:

2016419145837034.gif (422×670)

動畫有點長,耐心點看,一定要注意,是對當前View還是其他Views設置的動畫。
當然了動畫支持自定義,還支持設置時間,比如我們修改下,添加的動畫為:

mTransition.setAnimator(LayoutTransition.APPEARING, (mAppear         .isChecked() ? ObjectAnimator.ofFloat(this, "scaleX", 0, 1)         : null)); 

則效果為:

2016419145900874.gif (406×346)

原本的淡入,變成了寬度從中間放大的效果~~是不是還不錯~~

3、View的anim方法
在SDK11的時候,給View添加了animate方法,更加方便的實現動畫效果。
布局文件:

<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"    >    <ImageView     android:id="@+id/id_ball"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:src="@drawable/bol_blue" />    <LinearLayout     android:layout_width="fill_parent"     android:layout_height="wrap_content"     android:layout_alignParentBottom="true"     android:orientation="horizontal" >      <Button       android:layout_width="wrap_content"       android:layout_height="wrap_content"       android:onClick="viewAnim"       android:text="View Anim" />      <Button       android:layout_width="wrap_content"       android:layout_height="wrap_content"       android:onClick="propertyValuesHolder"       android:text="PropertyValuesHolder " />         </LinearLayout>  </RelativeLayout> 

代碼:

package com.example.zhy_property_animation;  import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.app.Activity; import android.os.Bundle; import android.util.DisplayMetrics; import android.util.Log; import android.view.View; import android.widget.ImageView;  public class ViewAnimateActivity extends Activity {   protected static final String TAG = "ViewAnimateActivity";    private ImageView mBlueBall;   private float mScreenHeight;    @Override   protected void onCreate(Bundle savedInstanceState)   {     super.onCreate(savedInstanceState);     setContentView(R.layout.view_animator);      DisplayMetrics outMetrics = new DisplayMetrics();     getWindowManager().getDefaultDisplay().getMetrics(outMetrics);     mScreenHeight = outMetrics.heightPixels;     mBlueBall = (ImageView) findViewById(R.id.id_ball);    }    public void viewAnim(View view)   {     // need API12     mBlueBall.animate()//         .alpha(0)//         .y(mScreenHeight / 2).setDuration(1000)         // need API 12         .withStartAction(new Runnable()         {           @Override           public void run()           {             Log.e(TAG, "START");           }           // need API 16         }).withEndAction(new Runnable()         {            @Override           public void run()           {             Log.e(TAG, "END");             runOnUiThread(new Runnable()             {               @Override               public void run()               {                 mBlueBall.setY(0);                 mBlueBall.setAlpha(1.0f);               }             });           }         }).start();   }  }         

                                                                                                       

簡單的使用mBlueBall.animate().alpha(0).y(mScreenHeight / 2).setDuration(1000).start()就能實現動畫~~不過需要SDK11,此后在SDK12,SDK16又分別添加了withStartAction和withEndAction用于在動畫前,和動畫后執行一些操作。當然也可以.setListener(listener)等操作。
使用ObjectAnimator實現上面的變化,我們可以使用:PropertyValueHolder

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,       0f, 1f);   PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 0,       mScreenHeight / 2, 0);   ObjectAnimator.ofPropertyValuesHolder(mBlueBall, pvhX, pvhY).setDuration(1000).start(); 

效果與上面一樣。
運行結果:

2016419150021670.gif (793×406)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 浏阳市| 综艺| 黔东| 涪陵区| 太仆寺旗| 鹤峰县| 桂平市| 屯留县| 林芝县| 梁山县| 修水县| 化德县| 茌平县| 万山特区| 石台县| 宁国市| 台南县| 宜兰县| 襄汾县| 城市| 襄城县| 稷山县| 芒康县| 舟山市| 凤庆县| 双辽市| 红安县| 江山市| 苍溪县| 墨脱县| 卢氏县| 哈尔滨市| 衡阳县| 荣成市| 五峰| 凯里市| 丰宁| 鹤壁市| 健康| 贡觉县| 那坡县|