1.プロパティアニメーション
プロパティ アニメーション
アニメーション 一般的なアニメーションは、先ほど学習したフレーム アニメーションとトゥイーン アニメーションです。Animator は、このセクションで説明するアニメーションの属性です。
1.1 プロパティ アニメーションの概要
1.1.1 属性アニメーションを導入する理由
- トゥイーン アニメーション機能は比較的単調で、4 つのアニメーション (透明度、回転、傾斜、移動) しかありません。
- トゥイーンアニメーションの対象はUIコントロールのみ
- トゥイーン アニメーションはビューの表示効果のみを変更し、ビューのプロパティは変更しません。
例: 左のボタンは右に移動されますが、この時点ではまだボタンは左にあります. 右のボタンをクリックすると、ボタンのクリックイベントはトリガーされません~
1.1.2 属性アニメーションとは
- Android 3.0 の導入はトゥイーン アニメーションの強化版と言え、4 種類のアニメーション効果を実現できるだけでなく、プロパティの変更も定義できます。
- アニメーションを実行するオブジェクトは、U コントロールだけではありません。任意のオブジェクトをアニメーション化できます (画面に表示されているかどうかに関係なく)
- アトリビュート アニメーションは、ターゲット オブジェクトに値を割り当てることによってそのアトリビュートを変更し、上記のボタンの問題は存在しません。
1.1.3 属性アニメーション関連のAPI
API | 例証する |
---|---|
アニメーター | 通常、アトリビュート アニメーションを作成するための基本クラスは直接使用されず、通常はその 2 つのサブクラスが使用されます。 |
バリューアニメーター | 前述のように、属性アニメーションは値を連続的に変更することで実現され、初期値と終了値の間の遷移アニメーションはこのクラスによって計算されます。内部的には、タイム ループ メカニズムを使用して値間のアニメーション遷移を計算します. クラスに初期値と終了値を提供し、アニメーションの持続時間を伝えるだけで、クラスはからの遷移を自動的に完了します.初期値から終了値へスムーズに遷移する効果! さらに、アニメーションの再生回数や再生モード、アニメーションのリスナー設定などもこのクラスが担当! |
オブジェクトアニメーター | ValueAnimator のサブクラスを使用すると、指定したオブジェクトのプロパティをアニメーション化できます。これは使いやすく、実際により多く使用されます。もちろん、ValueAnimator を使用する必要がある場合もあります。 |
アニメーターセット | 複数のアニメーターを結合し、複数のアニメーターを順番に再生するか、同時に再生するかを指定するために使用される、アニメーターのサブクラス |
評価者 | アニメーション システムに初期値から終了値への遷移方法を伝えるために、次の Evaluator が用意されています。 - IntEvaluator: int 型属性の値を計算する計算機 - FloatEvaluator: float 型の値を計算する計算機属性 - ArgbEvaluator: Calculator を使用して、16 進数形式で表される色の値を計算します - TypeEvaluator: 計算機のインターフェイス。このインターフェイスを実装して、カスタム計算機を完成させることができます |
1.2 ValueAnimator の簡単な使い方
1.2.1 使用プロセス:
- ValueAnimator のofInt ()、ofFloat ()、またはofObject () 静的メソッドを呼び出して、ValueAnimator インスタンスを作成します。
- インスタンスの setXxx メソッドを呼び出して、アニメーションの長さ、補間方法、繰り返し回数などを設定します。
- インスタンスのaddUpdateListener を呼び出してAnimatorUpdateListenerリスナーを追加すると、ValueAnimator によって計算された値が取得され、その値が指定されたオブジェクトに適用されます。
- インスタンスの **start()** メソッドを呼び出して、アニメーションを開始します! さらに、ofInt と ofFloat の両方に次のようなパラメータがあることがわかります: float/int... 値は複数の値を表します!
コードの実装:
レイアウト ファイル: activity_main.xml、非常にシンプル、4 つのボタン、1 つの ImageView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ly_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="动画1" />
<Button
android:id="@+id/btn_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="动画2" />
<Button
android:id="@+id/btn_three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="动画3" />
<Button
android:id="@+id/btn_four"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="动画4" />
<ImageView
android:id="@+id/img_babi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@mipmap/img_babi" />
</LinearLayout>
次に、 MainActivity.javaに移動します。まず、ビューの位置を変更するメソッドが必要です。ここでmoveView () を呼び出して、左と上の開始座標と幅と高さを設定します。
次に、線形移動、スケーリング、回転と透明度、および円形回転の 4 つのアニメーションが定義されます。
次に、ボタンを介して対応するアニメーションをトリガーします〜
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_one;
private Button btn_two;
private Button btn_three;
private Button btn_four;
private LinearLayout ly_root;
private ImageView img_babi;
private int width;
private int height;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindViews();
}
private void bindViews() {
ly_root = (LinearLayout) findViewById(R.id.ly_root);
btn_one = (Button) findViewById(R.id.btn_one);
btn_two = (Button) findViewById(R.id.btn_two);
btn_three = (Button) findViewById(R.id.btn_three);
btn_four = (Button) findViewById(R.id.btn_four);
img_babi = (ImageView) findViewById(R.id.img_babi);
btn_one.setOnClickListener(this);
btn_two.setOnClickListener(this);
btn_three.setOnClickListener(this);
btn_four.setOnClickListener(this);
img_babi.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_one:
lineAnimator();
break;
case R.id.btn_two:
scaleAnimator();
break;
case R.id.btn_three:
raAnimator();
break;
case R.id.btn_four:
circleAnimator();
break;
case R.id.img_babi:
Toast.makeText(MainActivity.this, "不愧是你", Toast.LENGTH_SHORT).show();
break;
}
}
//定义一个修改ImageView位置的方法
private void moveView(View view, int rawX, int rawY) {
int left = rawX - img_babi.getWidth() / 2;
int top = rawY - img_babi.getHeight();
int width = left + view.getWidth();
int height = top + view.getHeight();
view.layout(left, top, width, height);
}
//定义属性动画的方法:
//按轨迹方程来运动
private void lineAnimator() {
width = ly_root.getWidth();
height = ly_root.getHeight();
ValueAnimator xValue = ValueAnimator.ofInt(height,0,height / 4,height / 2,height / 4 * 3 ,height);
xValue.setDuration(3000L);
xValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 轨迹方程 x = width / 2
int y = (Integer) animation.getAnimatedValue();
int x = width / 2;
moveView(img_babi, x, y);
}
});
xValue.setInterpolator(new LinearInterpolator());
xValue.start();
}
//缩放效果
private void scaleAnimator(){
//这里故意用两个是想让大家体会下组合动画怎么用而已~
final float scale = 0.5f;
AnimatorSet scaleSet = new AnimatorSet();
ValueAnimator valueAnimatorSmall = ValueAnimator.ofFloat(1.0f, scale);
valueAnimatorSmall.setDuration(500);
ValueAnimator valueAnimatorLarge = ValueAnimator.ofFloat(scale, 1.0f);
valueAnimatorLarge.setDuration(500);
valueAnimatorSmall.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float scale = (Float) animation.getAnimatedValue();
img_babi.setScaleX(scale);
img_babi.setScaleY(scale);
}
});
valueAnimatorLarge.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float scale = (Float) animation.getAnimatedValue();
img_babi.setScaleX(scale);
img_babi.setScaleY(scale);
}
});
scaleSet.play(valueAnimatorLarge).after(valueAnimatorSmall);
scaleSet.start();
//其实可以一个就搞定的
// ValueAnimator vValue = ValueAnimator.ofFloat(1.0f, 0.6f, 1.2f, 1.0f, 0.6f, 1.2f, 1.0f);
// vValue.setDuration(1000L);
// vValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
// @Override
// public void onAnimationUpdate(ValueAnimator animation) {
// float scale = (Float) animation.getAnimatedValue();
// img_babi.setScaleX(scale);
// img_babi.setScaleY(scale);
// }
// });
// vValue.setInterpolator(new LinearInterpolator());
// vValue.start();
}
//旋转的同时透明度变化
private void raAnimator(){
ValueAnimator rValue = ValueAnimator.ofInt(0, 360);
rValue.setDuration(1000L);
rValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int rotateValue = (Integer) animation.getAnimatedValue();
img_babi.setRotation(rotateValue);
float fractionValue = animation.getAnimatedFraction();
img_babi.setAlpha(fractionValue);
}
});
rValue.setInterpolator(new DecelerateInterpolator());
rValue.start();
}
//圆形旋转
protected void circleAnimator() {
width = ly_root.getWidth();
height = ly_root.getHeight();
final int R = width / 4;
ValueAnimator tValue = ValueAnimator.ofFloat(0,
(float) (2.0f * Math.PI));
tValue.setDuration(1000);
tValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 圆的参数方程 x = R * sin(t) y = R * cos(t)
float t = (Float) animation.getAnimatedValue();
int x = (int) (R * Math.sin(t) + width / 2);
int y = (int) (R * Math.cos(t) + height / 2);
moveView(img_babi, x, y);
}
});
tValue.setInterpolator(new DecelerateInterpolator());
tValue.start();
}
}
プロセスは非常に簡単です.まず ValueAnimator オブジェクトを作成し、ValueAnimator.ofInt/ofFloat を呼び出してそれを取得し、次にアニメーションの長さを設定し、addUpdateListener を使用してAnimatorUpdateListenerイベントリスナーを追加し、パラメータanimationのgetAnimatedValue ()を使用してこの値を使用してビューのいくつかのプロパティを変更し、いわゆるアニメーション効果を形成し、setInterpolator アニメーション レンダリング モードを設定し、最後に start() を呼び出してアニメーションの再生を開始します。
1.3 ObjectAnimator の簡単な使い方
ObjectAnimator は、ValueAnimator よりも使いやすく、このクラスを介して、任意のオブジェクトの任意のプロパティを直接 アニメーション化できます。そうです、View オブジェクトに限らず、どんなオブジェクトでも、常にオブジェクト内のプロパティに値を代入し、オブジェクトのプロパティ値の変化に応じて表示方法を決定するのです! たとえば、TextView に次のアニメーションを設定します: ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f);ここでは、alpha の値を 1f から 0f に絶えず変更します。プロパティ値の変更により、フェードインとフェードアウトの効果が表示されますが、TextView クラスにはアルファ属性はありません ObjectAnimator の内部メカニズムは次のとおりです: 送信された属性 name~ に対応する get メソッドと set メソッドを見つけます。属性値ではありません!信じられない場合は、TextView のソース コードにアクセスして、alpha 属性があるかどうかを調べることができます。それではObjectAnimatorを使って4種類のトゥイーンアニメーションの効果を実現してみましょう~
コードの実装:
上記のレイアウトをそのままレイアウトに使用し、ボタンを追加し、ImageViewをTextViewに置き換えます.コードはここに掲載されておらず、 MainActivity.java部分のコードは実際には同じです〜
public class MainActivity5 extends AppCompatActivity implements View.OnClickListener {
private Button btn_one;
private Button btn_two;
private Button btn_three;
private Button btn_four;
private Button btn_five;
private LinearLayout ly_root;
private TextView tv_show;
private int height;
private ObjectAnimator animator1;
private ObjectAnimator animator2;
private ObjectAnimator animator3;
private ObjectAnimator animator4;
private AnimatorSet animSet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main5);
bindViews();
initAnimator();
}
private void bindViews() {
ly_root = (LinearLayout) findViewById(R.id.ly_root);
btn_one = (Button) findViewById(R.id.btn_one);
btn_two = (Button) findViewById(R.id.btn_two);
btn_three = (Button) findViewById(R.id.btn_three);
btn_four = (Button) findViewById(R.id.btn_four);
btn_five = (Button) findViewById(R.id.btn_five);
tv_pig = (TextView) findViewById(R.id.tv_pig);
height = ly_root.getHeight();
btn_one.setOnClickListener(this);
btn_two.setOnClickListener(this);
btn_three.setOnClickListener(this);
btn_four.setOnClickListener(this);
btn_five.setOnClickListener(this);
tv_pig.setOnClickListener(this);
}
//初始化动画
private void initAnimator() {
animator1 = ObjectAnimator.ofFloat(tv_pig, "alpha", 1f, 0f, 1f, 0f, 1f);
animator2 = ObjectAnimator.ofFloat(tv_pig, "rotation", 0f, 360f, 0f);
animator3 = ObjectAnimator.ofFloat(tv_pig, "scaleX", 2f, 4f, 1f, 0.5f, 1f);
animator4 = ObjectAnimator.ofFloat(tv_pig, "translationY", height / 8, -100, height / 2);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_one:
animator1.setDuration(3000l);
animator1.start();
break;
case R.id.btn_two:
animator2.setDuration(3000l);
animator2.start();
break;
case R.id.btn_three:
animator3.setDuration(3000l);
animator3.start();
break;
case R.id.btn_four:
animator4.setDuration(3000l);
animator4.start();
break;
case R.id.btn_five:
//将前面的动画集合到一起~
animSet = new AnimatorSet();
animSet.play(animator4).with(animator3).with(animator2).after(animator1);
animSet.setDuration(5000l);
animSet.start();
break;
case R.id.tv_pig:
Toast.makeText(MainActivity.this, "不愧是你", Toast.LENGTH_SHORT).show();
break;
}
}
}
1.4 XML を使用してアニメーションを作成する
XML を使用してアニメーションを作成すると、Java コードよりも描画に時間がかかる場合がありますが、再利用ははるかに簡単です。対応する XML タグは次のとおりです。 < animator >< objectAnimator >< set > 関連する属性は次のとおりです。
- android:ordering : アニメーションの再生順序を指定します。
- android:duration : アニメーションの長さ
- android:propertyName = "x": x ここで、上記の「アルファ」を覚えていますか? アニメーションをロードするオブジェクトは getx メソッドと setx メソッドを定義する必要があり、objectAnimator はこれを使用してオブジェクトの値を変更します!
- android:valueFrom ="1" : アニメーション開始の初期値
- android:valueTo ="0" : アニメーション終了時の最終値
- android:valueType ="floatType": 変化する値のデータ型
使用例は次のとおりです。
animator/property_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together" >
<objectAnimator
android:duration="3000"
android:propertyName="translationX"
android:valueFrom="-500"
android:valueTo="0"
android:valueType="floatType" >
</objectAnimator>
<objectAnimator
android:duration="3000"
android:propertyName="rotation"
android:repeatCount="3"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType" >
</objectAnimator>
</set>
アニメーション ファイルをロードします。
Animator animator = AnimatorInflater.loadAnimator(MainActivity5.this, R.animator.property_animator);
animator.setTarget(tv_show);
animator.start();
android:duration="3000"
android:propertyName="rotation"
android:repeatCount="3"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType" >
</objectAnimator>
```
アニメーション ファイルをロードします。
Animator animator = AnimatorInflater.loadAnimator(MainActivity5.this, R.animator.property_animator);
animator.setTarget(tv_show);
animator.start();
1.5 バターナイフ バターナイフの基本的な使い方
1.5.1 写真によると
1.5.2 上の図の実装の 4 番目のステップの 2 つの文
'com.jakewharton:butterknife:10.2.3'// この依存関係の
注釈を追加しますProcessor 'com.jakewharton:butterknife-compiler:10.2.3'// このルールを追加します
1.5.3 ID の取得
1.5.4 バインディングの初期化