ラベル Android の投稿を表示しています。 すべての投稿を表示
ラベル Android の投稿を表示しています。 すべての投稿を表示

2013年11月30日土曜日

[Androidアニメーション] 5. Drawable Animation

AndroidのAPIににおける2Dアニメーションの種類は主に3種類あります。

Property Animation

Android3.0(API level 11)からサポートされ、どんなオブジェクトにもアニメーションを行うことができる
View Animation
Viewsに回転、移動、拡大縮小、透明度変換などのアニメーションが行える
Drawable Animation
パラパラ漫画のようにフレームを連続再生することができる
ここでは、Developer AndroidのDrawable Animationの中身をかいつまんで、Drawable Animationについて紹介します。

Drawable Animationとは

Drawable Animationは、Drawable リソースを使って、連続的に表示をすることによってアニメーションを作ることが出来ます。フィルムのような役割をし、順番に沿って、連続した異なった画像を表示して行く従来のアニメーションです。AnimationDrawableクラスは 
Drawable Animationのためのクラスになります。

プログラムの中で、アニメーションのフレームを定義し、AnimationDrawableクラスのAPIを使って、アニメーションを構成するフレームをリスト化したXMLファイルによって簡単に行うことが出来ます。このXMLファイルはAndroidプロジェクトのres/drawable/に置きます。この場合、アニメーションの各フレームに順番と継続時間を指定します。

XMLファイルには、ルートノードとして、<animation-list>要素と連続したフレーム<item>ノードを指定します。XMLファイルの例は以下の通りです。

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>
このアニメーションは、3フレームのみです。listのandroid:oneshotの属性をtrueにセットすることによって、1回で停止し、最後にラストのフレームを表示します。falseをセットするとアニメーションは繰り返します。プロジェクトのres/drawable/ディレクトリに保存されたrocket_thrust.xmlを、Viewに背景画像として指定することが出来ます。ここでのActivityの例は、ImageViewにアニメーションを加え、スクリーンにタッチした時に、アニメーションが始まるプログラムです。
AnimationDrawable rocketAnimation;
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
  rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
  rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
}
public boolean onTouchEvent(MotionEvent event) {
  if (event.getAction() == MotionEvent.ACTION_DOWN) {
    rocketAnimation.start();
    return true;
  }
  return super.onTouchEvent(event);
}
AnimationDrawableで呼ばれるstart()は、onCreate()の中では呼ぶことができません。AnimationDrawableがウィンドウ上にまだ配置されていないからです。もし、アニメーションをすぐに始めたい場合、interactionを要求することなしに、Windowにフォーカスされた時に呼ばれるonWindowFocusChanged()から呼ぶことが出来ます。

XMLを使用しないサンプルプログラム

XMLファイルを使用しないサンプルプログラムは以下の通りです。Activityの中のみでアニメーションを指定することが出来ます。ここでは3フレームを使った250msごとにフレームが変化するアニメーションを説明しています。

public class DrawableAnimation extends Activity{
 
 AnimationDrawable mAnimationDrawable;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
     setContentView(R.layout.drawable_animation);
     //Drawable Animation: Changing Images ----------------------------------------------
     //Create AnimationDrawable
     mAnimationDrawable = new AnimationDrawable();
     //Set frames
     Drawable[] mFrame = new Drawable[3];
     mFrame[0] = getResources().getDrawable( R.drawable.img1);
     mFrame[1] = getResources().getDrawable( R.drawable.img2);
     mFrame[2] = getResources().getDrawable( R.drawable.img3);
    
     //Add frames to AnimationDrawable
     for(int i = 0; i < mFrame.length; i++){
      mAnimationDrawable.addFrame( mFrame[i],  250);
     }
     ImageView imageView = (ImageView) findViewById(R.id.imageView1);
     //Set the animation to background drawable
     imageView.setBackground(mAnimationDrawable);
     //Animation starts
     imageView.post(new Runnable(){
         public void run(){
          mAnimationDrawable.setOneShot(false);
          mAnimationDrawable.start();
        
         }
     });          
 }

まず最初に11行目でAnimationDrawableのコンストラクタをセットしています。
13行目では、フレームにDrawableリソースをセットします。各画像は、res/drawableの中に置きます。ここでは3フレームのアニメーションを行っています。
20行目では、各フレームをAnimationDrawableにセットしています。ここでのパラメータは以下の通りです。
addFrame(Drawable frame, int duration)
  • Drawable frame: フレームとしてのDrawableリソース(画像)
  • int duration: このフレームの継続時間

24行目では、ImageViewの背景画像として、アニメーションをセットしています。
onCreate()の中では、まだリソースがセットされていないので、直接onCreate()の中でアニメーションを始めることはできません。そこで、26行目のようにImageView.postを使用します。これは、ImageViewに背景画像がセットされたら呼ばれるので、ここで、AnimationDrawable.start()を指定します。

2013年11月27日水曜日

[Androidアニメーション] 4. View Animation

AndroidのAPIににおける2Dアニメーションの種類は主に3種類あります。

Property Animation

Android3.0(API level 11)からサポートされ、どんなオブジェクトにもアニメーションを行うことができる
View Animation
Viewsに回転、移動、拡大縮小、透明度変換などのアニメーションが行える
Drawable Animation
パラパラ漫画のようにフレームを連続再生することができる

ここでは、Developer AndroidのView Animationの中身をかいつまんで、View Animationについて紹介します。

View Animationとは 

View Animationでは、View上にTween Animationを表示することが出来ます。Tween Animationはスタートポイント、エンドポイント、サイズ、回転や共通の縦横比などのアニメーション情報を計算します。

Tween AnimationはViewオブジェクトのコンテンツ上で、位置、サイズ、回転や透明度などの単純な変換を行うことが出来ます。例えば、TextViewオブジェクトにおいて、テキストの移動、回転、拡大縮小などができます。もし、TextViewに背景画像が設定してあれば、背景画像はテキストと一緒に変換されます。

アニメーションの手順はXMLかコードで書くことができます。ここではコードでのアニメーションの実行の仕方を紹介します。

View Animationはandroid.view.animation パッケージの中にあるクラスを使うことが出来ます。Viewに使えるアニメーションは4つあります。
  • Scale Animation: サイズの変更
  • Translate Animation: Viewの移動
  • Alpha Animation:透明度の設定
  • Rotate Animation:与えられた角度だけ回転
各アニメーションは、android.view.animationsの中にそれぞれクラスを持っています。すべてのアニメーションクラスは、抽象Animationクラスを拡張したものです。図1はこれらのクラスの階層を示しています。
図1ではAnimationSetというクラスがありますが、このクラスは、アニメーションのグループをつくることができ、同時にいくつかのアニメーションを行ったり、連続してアニメーションを行ったりする時などに使うことができます。
図1: View Animationのクラス階層

サンプルプログラム

サンプルプログラムでは、各アニメーションクラスの簡単な例をViewAnimationクラスとして書いています。それぞれのアニメーションにおいて、繰り返しモードsetRepeatMode()の設定で、逆戻りAnimation.REVERSEを指定しています。


public class ViewAnimation extends Activity {

 ImageView setImageView;
 AnimationSet animationSet;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.view_animation);
     
        //Scale Animation Sample---------------------------------------------------
  ImageView scaleImageView = (ImageView) findViewById(R.id.imageView1);
  ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 0.5f, 1.0f, 0.5f, 0, 0);
  scaleAnimation.setStartOffset(1000);
  scaleAnimation.setDuration(2000);
  scaleAnimation.setRepeatCount(Animation.INFINITE);
  scaleAnimation.setRepeatMode(Animation.REVERSE);
  scaleImageView.startAnimation(scaleAnimation);
  
  //Translate Animation Sample----------------------------------------------
  ImageView transImageView = (ImageView) findViewById(R.id.imageView2);
  TranslateAnimation transAnimation = new TranslateAnimation(0, 50, 0, 20);
  transAnimation.setDuration(3000);
  transAnimation.setRepeatCount(Animation.INFINITE);
  transAnimation.setRepeatMode(Animation.REVERSE);
  transImageView.startAnimation(transAnimation);
  
  //Alpha Animation Sample-------------------------------------------------
  ImageView alphaImageView = (ImageView) findViewById(R.id.imageView3);
  AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
  alphaAnimation.setDuration(3000);
  alphaAnimation.setRepeatCount(Animation.INFINITE);
  alphaAnimation.setRepeatMode(Animation.REVERSE);
  alphaImageView.startAnimation(alphaAnimation);
  
  //Set Animation Sample---------------------------------------------------
  setImageView = (ImageView) findViewById(R.id.imageView5);
  animationSet = new AnimationSet(false);
  //Animation1
  ScaleAnimation scaleAnimation1 = new ScaleAnimation(0.5f, 1.0f, 0.5f, 1.0f);
  scaleAnimation1.setDuration(3000);
  //Animation2
  AlphaAnimation alphaAnimation1 = new AlphaAnimation(0.0f, 1.0f);
  alphaAnimation1.setDuration(3000);
  
  animationSet.addAnimation(scaleAnimation1);
  animationSet.addAnimation(alphaAnimation1);
  setImageView.startAnimation(animationSet);
  
  //AnimationListener
  animationSet.setAnimationListener(new Animation.AnimationListener() {  
        
        public void onAnimationStart(Animation animation) { 
        
        }  
        
        public void onAnimationRepeat(Animation animation) {
      
        }  
        
        public void onAnimationEnd(Animation animation) {  
         setImageView.startAnimation(animationSet);
        }  
      }); 
 
 }
 
 @Override
  public void onWindowFocusChanged(boolean hasFocus) {
   super.onWindowFocusChanged(hasFocus);
   //Rotate Animation Sample ---------------------------------------------------
   ImageView rotateImageView = (ImageView) findViewById(R.id.imageView4);
  int centerX = (int)rotateImageView.getWidth()/2;
  int centerY = (int)rotateImageView.getHeight()/2;
  RotateAnimation rotateAnimation = new RotateAnimation(0, 20, centerX,centerY);
  rotateAnimation.setDuration(3000);
  rotateAnimation.setRepeatCount(Animation.INFINITE);
  rotateAnimation.setRepeatMode(Animation.REVERSE);
  rotateImageView.startAnimation(rotateAnimation);
  }
}

アニメーションの設定

アニメーションの設定は、どのクラスでも同じような設定を行うことが出来ます。例としてScaleAnimationを上げて説明します。
ImageView scaleImageView = (ImageView) findViewById(R.id.imageView1);
ScaleAnimation scaleAnimation = new ScaleAnimation(0.5f, 1.0f, 0.5f, 1.0f, 0, 0);
scaleAnimation.setStartOffset(1000);
scaleAnimation.setDuration(3000);
scaleAnimation.setRepeatCount(Animation.INFINITE);
scaleAnimation.setRepeatMode(Animation.REVERSE);
scaleImageView.startAnimation(scaleAnimation);

13行目でアニメーションのコンストラクタを指定します。14行目の遅延時間setStartOffset(ms)、15行目のアニメーションの継続時間setDuration(ms)、16行目の繰り返し情報setRepeatCount()、17行目の繰り返しモードsetRepeatMode()などを指定して、最後に18行目のようにアニメーションを行いたいViewのstartAnimation()にアニメーションをセットすることで、アニメーションが始まります。
setRepeatCountにAnimation.INFINITEを指定すると無限にアニメーションを繰り返します。setRepeatMode()では、単純な繰り返しAnimation.RESTARTか逆戻りAnimation.REVERSEを設定することが出来ます。


Scale Animation

拡大縮小を行うには、ScaleAnimationを使用します。13行目のScaleAnimationのコンストラクタのパラメータは以下の通りです。サンプルプログラムでは、0.5倍から1倍に拡大しています。
ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY);
  • float fromX: アニメーション開始のXスケール
  • float toX: アニメーション終了のXスケール
  • float fromY: アニメーション開始のYスケール
  • float toY: アニメーション終了のYスケール
  • float pivotX 原点となるX座標位置
  • float pivotY 原点となるY座標位置


Translate Animation

移動を行うには、TranslateAnimationを使用します。22行目のTranslateAnimationのコンストラクタのパラメータは以下の通りです。サンプルプログラムでは、元の位置(0, 0)からX座標に50ピクセル、Y座標に20ピクセル移動するアニメーションを指定しています。
TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta);
  • float fromXDelta: アニメーション開始時のView内のX座標
  • float toXDelta: アニメーション終了時のView内のX座標
  • float fromYDelta: アニメーション開始時のView内のY座標
  • float toYDelta: アニメーション終了時のView内のY座標


Alpha Animation

透明度変化には、AlphaAnimationを使用します。30行目のAlphaAnimationのコンストラクタのパラメータは以下の通りです。サンプルプログラムでは、不透明から透明へ変化しています。ここでのパラメータの値は、0.0〜1.0を指定します。0.0は完全に透明、1.0は完全に不透明を示します。
AlphaAnimation (float fromAlpha, float toAlpha);
  • float fromAlpha: アニメーション開始時の透明度を指定
  • float toAlpha: アニメーション終了時の透明度を指定


Rotate Animation

回転には、RotateAnimationを使用します。75行目のRorateAnimationのコンストラクタのパラメータは以下の通りです。サンプルプログラムでは、20度の回転を指定しています。回転の中心座標をViewの中心に指定しています。
RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY);
  • float fromDegrees: アニメーション開始時の回転角度
  • float toDegrees: アニメーション終了時の回転角度
  • float pivotX:回転の中心X座標
  • float pivotY: 回転の中心Y座標
サンプルプログラムでは、RotateAnimationをOnWindowFocusChangedの中で指定しています。これは、OnCreate内では早過ぎてViewのgetWidth(), getHeight()の値を取ることができず0が帰ってきてしまうからです。OnWindowFocusChanged内で呼ぶことで、値を得ることが出来ます。


Animation Set

複数のアニメーションを同時に行う場合には、AnimationSetを使用します。サンプルプログラムでは、scaleAnimation1とAlphaAnimation1のアニメーションをセットしています。AnimationSetでは、setRepeatCountが効きません。繰り返しを行いたい場合は、AnimationListenerを使用して、アニメーションの終了時にアニメーションの開始を指定することができます。
AnimationSet(boolean shareInterpolator);
  • boolean shareInterpolator: Interpolatorを共有するかどうかを指定


AnimationListener

51行目のAnimationListenerでは、アニメーションの開始、リピート、終了を監視することができます。ただし、AnimationSetではonAnimationRepeatは動作しません。

2013年11月16日土曜日

[Androidアニメーション] 3. Property Animation のプログラム

Android APIには2DAnimationが3種類用意されています。Property Animation, View Animation,Drawable Animationです。これらの違いの説明は1. Android Animationの種類紹介しています。
ここでは主にObject Animatorを使ったProperty Animationのサンプルプログラムを紹介します。Property Aniamtionの詳細な説明は2. Property Animationの説明で紹介しています。

  1. Android Animationの種類
  2. Property Animationの説明
  3. Property Animationのプログラム
  4. View Animation の説明とプログラム
  5. Drawable Animationの説明とプログラム


Property Animationのサンプルプログラム

サンプルではオブジェクトをButton 1とButton2とし、プロパティをButton 1ではテキストカラー、Button 2ではx方向の移動距離とするアニメーションを行っています。



public class SamplePropertyAnimation extends Activity {
 
 private static final int RED = 0xffFF8080;
 private static final int BLUE = 0xff8080FF;
 Button button1;
 Button button2;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  setContentView(R.layout.propertyanimation_main);
  
  //Property Animation: Changing TextColor
  button1 = (Button) findViewById(R.id.btn1);
  ObjectAnimator colorAnimator = ObjectAnimator.ofInt(button1,"textColor", RED, BLUE);
  colorAnimator.setDuration(3000);
  colorAnimator.setEvaluator(new ArgbEvaluator());
  colorAnimator.setRepeatCount(ValueAnimator.INFINITE);
  colorAnimator.setRepeatMode(ValueAnimator.REVERSE);
  colorAnimator.start();
     
  //Property Animation: Translation
  button2 = (Button) findViewById(R.id.btn2);
  ObjectAnimator transAnimator = ObjectAnimator.ofFloat(button2, "x", 0f, 100f);
  transAnimator.setDuration(5000);
  transAnimator.setRepeatCount(2);
  transAnimator.setInterpolator(new BounceInterpolator());
  transAnimator.addListener(new AnimatorListenerAdapter(){
   @Override
   public void onAnimationEnd(Animator animation){
    //Write processing after animating
    button2.setVisibility(View.GONE);
   } 
  });
  transAnimator.start();
  
 }

}
16行目でObjectAnimatorにアニメーションしたいオブジェクトとプロパティを設定します。
ObjectAnimator colorAnimator = ObjectAnimator.ofInt(button1,"textColor", RED, BLUE);
1.ターゲットとなるオブジェクト:ここではButtonを設定。
2.プロパティの名前(String):ここでは"textColor"を設定。
3.開始のプロパティの値
4.終了時のプロパティの値
17行目でアニメーションの継続時間をmsで設定します。デフォルトでは300msが設定されています。 

18行目でEvaluatorを設定します。Evaluatorsは与えられたプロパティ値をどのように計算するか指定します。ここでは色の変化をアニメーションするので、ArgbEvaluator()を設定しています。Evaluatorの種類は以下の通りです。
  • IntEvaluator: int プロパティの値を計算。
  • FloatEvaluator:  floatプロパティの値を計算。
  • ArgbEvaluator:  16進数で表されるカラープロパティの値を計算。
  • TypeEvaluator: カスタマイズのエバリュエータを作ることが出来るインターフェース。もし、int, float, colorではないオブジェクトプロパティにアニメーションをしたい場合、オブジェクトプロパティの値をどのように計算をするか指定することができます。

21行目でアニメーションをスタートします。

28行目ではアニメーションの速度を示すInterpolatorを設定しています。Interpolatorはアニメーションで指定された値がタイム機能としてどのように計算されるか定義することができます。例えば、全体のアニメーションを通して、連続的に起こるアニメーションを指定するか、またはアニメーションの始まりと終わりで加速するようなの不連続的なアニメーションを指定するかなど選択できます。android.view.animationに含まれるInterpolatorは以下の種類があります。
  • AccelerateDecelerateinterpolator: 最初最後がゆっくりになり、真ん中で加速する。 
  • AccelerateInterpolator: ゆっくりで始まり、徐々に加速して行く。 
  • AnticipateInterpolator: 開始時に逆方向にためる。 
  • AnticipateOvershootInterpolator:  開始時に逆方向にため、終了時にはみ出す。 
  • BounceInterpolator: 終了時にバウンドする。 
  • AnticipateOvershootInterpolator: 開始時に逆方向にため、終了時にはみ出す。 
  • CycleInterpolator: 指定された回数アニメーションを繰り返す。 
  • DecelerateInterpolator: 開始時に素早く徐々に速度を落とす。 
  • LinearInterpolator: 一定に変化させる。 
  • OvershootInterpolator: 終了時にはみ出す。
  • TimeInterpolator: カスタマー実装を行う。
29行目ではAnimationListenersを設定しています。これは、アニメーションが行われている間のイベントを監視することができます。例では、アニメーション終了時にボタンを消去しています。Listenersでは以下のイベントをキャッチすることができます。
  • onAnimationStart() アニメーション開始時に呼ばれる。
  • onAnimationEnd() アニメーション終了時に呼ばれる。
  • onAnimationRepeat() アニメーション繰り返し時に呼ばれる。
  • onAnimationCancel() キャンセル時に呼ばれる。このとき、onAnimationEnd()も同時に呼ばれる。


2013年11月15日金曜日

[Androidアニメーション] 2. Property Animationの説明

AndroidのAPIににおける2Dアニメーションの種類は主に3種類あります。

Property Animation
Android3.0(API level 11)からサポートされ、どんなオブジェクトにもアニメーションを行うことができる
View Animation
Viewsに回転、移動、拡大縮小、透明度変換などのアニメーションが行える
Drawable Animation
パラパラ漫画のようにフレームを連続再生することができる

ここでは、Developer AndroidのProperty Animationの中身をかいつまんで、Property Animationについて紹介します。サンプルプログラムについては、Property Animationのサンプルプログラムの説明で紹介しています。

Property Animationとは

Android3.0(API level 11)からサポートされ、Viewに限らず、どんなオブジェクトのプロパティにも指定した時間間隔で、アニメーションを行うことができます。ここでいうプロパティとはアニメーションに必要な設定値を指しています(例えば、色の変化値、透明度など)。このシステムは拡張性があり、カスタムタイプのプロパティにも適しています。Property Animationには以下のようなアニメーション機能を定義することができます。
継続時間(Duration): アニメーションの継続時間を指定することが出来ます。デフォルトは300msです。

補間時間(Time interpolation): アニメーションの現在の経過時間の機能として、プロパティの値がどのように計算されるか指定することが出来ます。
繰り返し(Repeat count and behavior): アニメーションの繰り返し回数や振る舞いなどを指定することが出来ます。

アニメーションのセット機能(Animator sets): 複数のアニメーションをグループ化して表示することができます。連続回数や、遅延などを指定することができます。
フレーム更新の遅延(Frame refresh delay): フレーム更新の時間を指定することが出来ます。デフォルトの設定は10msごとですが、アプリケーションのスピードに依存します。

Property Animationの動き

アニメーションがどのように行われるか簡単な例を紹介します。図1はプロパティxを持つオブジェクトを示しています。ここでプロパティxは画面のx方向への位置を表しているとします。アニメーションの継続時間を40msに設定し、移動距離を40pixelsとします。すると10 msごと、フレームが更新され10pixelsごとx方向にオブジェクトが移動します。この例では、補間時間の設定に、一定のスピードで物体が動くlinear interpolationを指定しています。

図1.Linear Interpolationの例

またスピードが変化するnon-linear interpolationも指定することが出来ます。図2はアニメーションの開始時に加速をし、中間からまた徐々に最後まで加速をするというアニメーションを示しています。オブジェクトは40msに40pixels移動しますが、速度が変化しています。


図2.non-linear Interpolationの例

Property Animationが上のようなアニメーションをどのように計算しているか説明していきます。図3はメインクラスと他のクラスの関係を示しています。


図3.アニメーションの計算の仕方

ValueAnimatorオブジェクトは継続時間やプロパティの現在の値などのアニメーションのタイミングを監視しています。ValueAnimatorはアニメーションの補間時間を定義しているTimeInterpolator、プロパティの値の計算方法を定義するTypeEvaluatorをカプセル化しています。例えば、図2ではTimeInterpolatorはAccelerateDecelerateInterpolatorをTypeEvaluatorにはIntEvaluatorが設定されています。

アニメーションを開始するには、ValueAnimatorを作り、アニメーションしたいプロパティの最初と最後の値を設定します。start()を呼ぶとアニメーションが始まります。アニメーションの間、ValueAnimatorはアニメーションの継続時間とどれくらい経過したかで、0から1の間でその割合を計算します。経過割合はアニメーションがどれくらい経過したかを0が0%を1が100%で示しています。例えば図1では、t=10での経過割合は全体の時間が40msなので、0.25になります。

ValueAnimatorが経過割合を計算しているとき、補間割合を計算するために、現在セットされているTimeInterpolatorが呼ばれます。補間割合はセットされた時間補間を考慮して新しい割合を時間補間にセットします。例えば図2でじゃ、アニメーションはゆっくり加速するので、t=10のとき、時間補間よりも小さい補間割合0.15となります。図1では補間割合は時間補間と同じように一定となります。

補間割合が計算されるときValueAnimatorはアニメーションの補間割合、始まりの値、終わりの値をもとに、プロパティの値を計算するために、適切なTypeEvaluatorを呼びます。例えば図2では補間割り肺はt=10msの時に0.15なので、この時間でのプロパティ値は0.15x(40 - 0)=6となります。

Property AnimationとView Animationの違いView AnimationシステムはViewオブジェクトにのみアニメーションを行うことが出来ます。もし、Viewオブジェクト以外にアニメーションを行いたい場合は、自信のコードを実行しなければいけません.View Animation システムは背景色の変更などはできず、Viewの回転や拡大縮小などアニメーションが限られています。さらにView Animationのデメリットは、実際のViewではなく表示されたViewのみを修正します。例えば、スクリーン上にボタンが動くアニメーションを行った場合、現在ある位置でボタンをクリックしても反応しません。自信でこれを修正する必要があります。

Property Animation システムはこれらの制約が取り除かれ、どんなオブジェクトのどんなプロパティにもアニメーションを行うことができ、オブジェクト自身も修正されます。Property Animationシステムはまたアニメーション実行においてさらにロバストになっています。ハイレベルで、animatorにアニメーションをしたいプロパティ(例えば色、位置やサイズなど)を指定をして複数のanimatorの同期や補間などのアニメーションのアスペクトを定義することができます。

View Animationシステムは短いセットアップ時間と少ないコードで設定できます。もしView Animationで自信のアニメーションが行えるのであればProperty Animationを使う必要はありません。異なった状況において両方のアニメーションシステムを使うことも可能です。

APIの概要

Property AnimationシステムのAPIはandroid.animationで定義されています。View Animationシステムではandroid.view.animationの中で、多くの補間機能が既に定義されていますが、Property Animationシステムでも同じようにこれらの機能を使うことが出来ます。以下では、Property Animationシステムの主な構成要素を示しています。

Animator クラスはアニメーションを構成する上で基本的なメソッドを定義したスーパークラスです。Animatorクラスは抽象クラスと定義されているため、直接インスタンス化することは出来ないので、通常Animatorクラスのサブクラスを使用します。サブクラスは主に3つ、ValueAnimator, ObjectAnimator, AnimatorSetがあります。主に、オブジェクトの属性などを設定するのには、ObjectAnimatorクラスを使います。

ValueAnimator

ValueAnimatorは、Property Animationのメインとなるタイミングエンジンです。プロパティ値を計算し、各アニメーションの詳細、繰り返し情報やイベントのアップデートを受け取るリスナーを含んでいます。アニメーションは、主に2つの部分に分けられます。アニメーション値の計算とアニメーションされるオブジェクトとプロパティにそれらの値を設定することです。ValueAnimatorでは、オブジェクトとプロパティに値を設定することができないので、自信のロジックでアニメーションをしたいオブジェクトに値をアップデートしていく必要があります。

ObjectAnimator

ValueAnimationのサブクラスで、ターゲットオブジェクトを設定することが出来ます。このクラスはアニメーションの値を計算する時に,それに応じてプロパティををアップデートします。ターゲットとなるオブジェクトにアニメーション値を設定できるので、簡単にアニメーションを行うことが出来ます。しかし、OjbectAnimationは現在のターゲットオブジェクトに特定のアクセッサーの方法を要求する場合に制限出てくるので、その時にはValueAnimationを直接使います。

AnimationSet

アニメーションをグループ化することができます。アニメーションの同時表示や連続表示、また指定した遅延時間後などを設定することが出来ます。

[Androidアニメーション] 1. アニメーションの種類

Androidフレームワークには、Android 3.0からサポートされているProperty Animationと従来からサポートされているView Animationがあります。Property AnimationはView Animationよりも柔軟性が高く多くの機能を持っているので、使いやすいと言えます。これらの2つのシステムに加えてDrawable Animationがあります。Drawable Animationではリソースをロードし、ぱらぱら漫画のように、連続したフレームで画像を表示することが出来ます。

Property Animation

Android3.0(API level 11)からサポートされ、Viewsに限らず、どんなオブジェクトのプロパティにも指定した時間間隔で、アニメーションを行うことができます。ここでいうプロパティとはアニメーションに必要な設定値を指しています(例えば、色の変化値、透明度など)。このシステムは拡張性があり、カスタムタイプのプロパティにも適しています。
サンプルプログラムの説明

View Animation

View Animationは、従来のシステムで、Viewsにのみアニメーションを行うことが出来ます。設定が簡単で、Viewsの移動、拡大縮小、透過度の変化など、基本的な機能を備えています。
サンプルプログラムの説明

Drawable Animation

Drawable Animationは、Drawable リソースを次から次へと表示することが出来きます。パラパラ漫画のような連続的なアニメーションを行うことが出来ます。
サンプルプログラムの説明




サンプルプログラムは、各アニメーションを最も簡単な例で示しています。詳細は各アニメーションの紹介ページ(Property Animation, View Animation, Drawable Animation)で説明しています。参考にしてください。


public class SampleAnimation extends Activity {
 
 private static final int RED = 0xffFF8080;
 private static final int BLUE = 0xff8080FF;
 
 AnimationDrawable mAnimationDrawable;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  setContentView(R.layout.activity_main);
  
  //Property Animation: Changing TextColor-------------------------------------
  Button btnColor = (Button) findViewById(R.id.btncolor);
  //Define an object and property in ObjectAnimator 
  ObjectAnimator animColor = ObjectAnimator.ofInt(btnColor,"textColor", RED, BLUE);
  //Set duration time (ms)
  animColor.setDuration(3000);
  //Set Evaluator, how to calculate the specified values.
  animColor.setEvaluator(new ArgbEvaluator());
  //Set repeat count
  animColor.setRepeatCount(ValueAnimator.INFINITE);
  //Set repeat mode
  animColor.setRepeatMode(ValueAnimator.REVERSE);
  //Animation starts
  animColor.start();
  
  //View Animation: Changing Transparency--------------------------------------
  Button btnAlpha = (Button) findViewById(R.id.btnalpa);
  //Set a value of transparency
  AlphaAnimation alp1 = new AlphaAnimation(1.0f, 0.0f);
  //Set duration time (ms)
  alp1.setDuration(3000);
  //Set repeat count
  alp1.setRepeatCount(Animation.INFINITE);
  //Animation starts
  btnAlpha.startAnimation(alp1);
     
  //Drawable Animation: Changing Images ----------------------------------------------
  //Create AnimationDrawable
  mAnimationDrawable = new AnimationDrawable();
  //Set frames
  Drawable[] mFrame = new Drawable[2];
  mFrame[0] = getResources().getDrawable( R.drawable.imgcat1);
  mFrame[1] = getResources().getDrawable( R.drawable.imgcat2);
  //Add frames to AnimationDrawable
  for(int i = 0; i < mFrame.length; i++){
   mAnimationDrawable.addFrame( mFrame[i],  200);
  }
  ImageView imageView = (ImageView) findViewById(R.id.image);
  //Set the animation to background drawable
  imageView.setBackgroundDrawable(mAnimationDrawable);
  //Animation starts
  imageView.post(new Runnable(){
      public void run(){
       mAnimationDrawable.setOneShot(false);
    mAnimationDrawable.start();
    
      }
  });
  
 }

}

2012年12月28日金曜日

アプリ内課金バージョン3 (In-App Billing Version 3)

ここではAndroid DevelopersのIn-app Billing Version 3のページを訳してみました。バージョン 3では、管理商品("managed products")のみをサポートしています。管理商品では、Google Playがユーザのアイテム所有の有無を全て管理してくれます。また、消費商品("consumable products")が扱えるようになりました。消費商品とは、ゲーム内の通貨など、アイテムが消費されるたび、再度購入ができるようになります。

In-app Billing Version 3
In-app Billing version 3 APIではアプリ内課金を簡単にあなたのアプリに統合することが出来ます。このバージョンは、改良された同期購入フロー、消費商品の所有の記録を簡単に行えるAPIやアプリ内購入データのローカルキャッシュなどの特徴を含んでいます。

Product Types
Google Play Developer Consoleを使って、商品タイプ、SKU、値段、説明文など、商品を定義することができます。詳細は、Administering In-app Billingを見てください。Version 3 APIは管理商品 ("managed products") のみサポートしています。

Managed In-app Products
アプリ内管理商品(managed in-app products) は、Google Playによって管理され記録された所有情報を持つアイテムです。ユーザが管理アイテムを購入したとき、Google Playは各ユーザごと、各アイテムの購入情報を保存します。特定ユーザが購入したアイテムの状態を復元するために、いつでもGoogle Playにクエリを送ることができます。ユーザがアプリをアンインストールしたり、ディバイスを変更したとしても、この情報はGoogle Play サーバ上に保存してあります。

Version 3 APIを使用する場合、アプリの中で管理アイテムを消費することができます。何度も購入することができるアイテム (例えばゲーム内の通貨、燃料や魔力など) の消費を実装することができます。いったん消費アイテムが購入されると、Google Playに消費リクエストを送ることでそのアイテムが消費されるまで、再び購入することは出来ません。商品の消費に関しての詳細は、Consuming Itemsを見てください。

Purchasing Items
Version 3 APIの購入の流れは以下の通りです。

  1. 使っているアプリ内課金 API のバージョンがサポートされているか確認するために、アプリはGoogle PlayにisBillingSupportedリクエストを送る。
  2. アプリがスタートしたときやユーザがログインしたとき、何のアイテムをユーザが所有しているか確定するために、Google Playでチェックすることを推奨します。ユーザのアプリ内商品の検索には、getPurchasesリクエストを送ります。リクエストが成功したら、Google Playは購入アイテムの商品IDのリスト、個々の購入アイテムの詳細リスト、購入のためのサインのリストを含んだBundleを返します。
  3. 通常、購入できる商品をユーザを知らせたいと思います。Google Playで定義した商品の詳細を検索するために、getSkuDetailsリクエストを送ることができます。検索リクエストには、商品IDのリストを明記する必要があります。リクエストが成功したら、Google Playは商品の値段、タイトル、詳細、購入タイプを含んだBundleを返します。
  4. 商品がユーザによって所有されていなかったら、購入プロセスを始めることができます。購入リクエストを始めるには、購入するアイテムの商品IDを他のパラメータと一緒にを明記した getBuyIntent リクエストを送ります。Developer Consoleで新しい商品を作るとき、商品IDを記録する必要があります。
a. Google Playは購入のためのチェックアウトUIをスタートするのに使うPendingIntentを含んだBundleを返します。 b. アプリはstartIntentSenderForResutメソッドを呼ぶことによってpending intentを立ち上げます。 c. チェックアウトフローが終了したとき (ユーザがアイテムを購入もしくは購入をキャンセルしたとき)、Google PlayはonActivityResultメソッドにレスポンスIntentを送ります。onActivityResutの結果コードは購入が行われたかキャンセルされたかどうかを示す結果コードを持っています。レスポンスIntentは購入されたアイテムについての情報を含んでいます。この購入取引を特定するために、レスポンス Intentはgoogle Playによって発行されたpurchaseToken Stringを含んでいます。このIntentはprivate developer key にサインした購入サインも含んでいます。
Version 3 APIのコールについて更に学びたい場合、In-app Billing Referenceをみてください。

Consuming Items
商品のユーザの所有状態を監視するために消費メカニズム 使用することができます。


バージョン3では、全てのアプリ内商品は管理されています。これは全てのアイテム購入のユーザの所有がGoogle Playによって保持されていることを意味します。そしてアプリ側は必要なときにユーザの購入情報を検索することができます。ユーザがアイテムの購入に成功したとき、その購入情報はGoogle Playに記録されます。一旦アイテムが購入されると、それは所有された("owned") 状態と見なされます。"owned"状態のアイテムはGoogle Play から購入することはできません。 Google Playが再び購入を可能にする前に、"owned"アイテムの消費リクエストを送らなければいけません。アイテムを消費するということは、非所有("unwoned")状態に戻り、前の購入データを破棄するということです。

ユーザの所有している商品リストを検索するには、アプリ側はgetPurchasesコールをGoogle Playに送ることができます。アプリ側はconsumePurchaseコールを送ることによって消費リクエストを作ることができます。リクエストの中で、購入時にGoogle Playから手に入れたアイテムの固有のpurchaseToken Stringを明確にしなければいけません。消費の登録に成功したら、Google Playはステータスコードを返します。

Non-consumable and consumable items

アプリ内商品を消費アイテムにするか非消費アイテムにするかは、あなた自身で決められます。

Non-consumable items
通常、アプリ内で一度だけ購入することができ、永続してベネフィットを提供するアイテムなので消費を実装をする必要はありません。一度購入したら、アイテムはユーザのGoogleアカウントに関連づけられます。非消費アイテムの例としてはプレミアムアップグレードやレベルパックなどです。

Consumable items
何度も購入することができるアイテムで消費を実装することができます。通常これらのアイテムは一時的な効果を提供します。例えば、ユーザのゲーム内でのキャラクターがライフポイントを得るためや、ゴールドコインを手に入れるなどです。アプリの中で購入したアイテムのベネフィットや効果を施すことは、商品をプロビジョニングするといいます。どのように商品がユーザに提供されるのか、開発者は、それを管理し記録する責任があります。
重要:アプリの中で消費アイテムをプロビジョニングする前に、Google Playに消費リクエストを送り、消費が記録されたことを指し示すレスポンスを受け取らなければいけません。

Managing consumable purchases in your application
消費アイテムを購入するための基本的な流れは以下のとおりです。

  1. getBuyIntentコールで購入フローを始めます。
  2. 購入が完全に成功したかどうかを示すBundleをGoogle Playから受け取ります。
  3. 購入が成功したら、consumePurchaseコールを作ることによって、購入を消費することができます。
  4. 消費が成功したかどうかを示す返答コードをGoogle Playから得ます。
  5. もし消費が成功したら、アプリの中で商品をプロビジョンします。
その後、ユーザがアプリをスタートアップもしくはログインするときには、ユーザが未処理の消費アイテムを所有しているかどうか確認しなければいけません。その場合、それらのアイテムの消費とプロビジョンが出来ているかを確認してください。ここではアプリの中で消費アイテムを実装するための推奨されたアプリのスタートアップの流れです。

  1. ユーザが所有しているアイテムを検索するためにgetPurchases リクエストを送ります。
  2. 何か消費アイテムがあったら、consumePurchaseを呼ぶことによってアイテムを消費します。消費アイテムの購入オーダが完了していて、しかし、消費リクエストを送る機会を持つ前に、ストップしてしまったりアクセスが切られてしまう場合があるので、このプロセスは必要です。
  3. 消費が完了したかどうかを示すレスポンスコードをGoogle Playから得ます。
  4. 消費が成功したら、アプリの中の商品をプレビジョンします。
Local Caching
Google playクライアントが、ディバイス上にin-appBilling情報をキャッシュすることができるので、更に頻繁にこれらの情報を検索するのに、例えば、getPurchasesコールを通して、Version3 APIを使うことができます。前のバージョンのAPIとは違い、Version 3 APIのコールは、Google Playに繋ぐネットワークコネクションの代わりにAPIの返答時間を十分にスピードアプしたキャッシュ検索を通して提供されます。

2012年12月22日土曜日

アプリ内課金概要 (In-app Billing Overview for Android)

Android DevelopersのIn-appBilling Overviewのページを訳しました。
アプリ内課金のバージョン2と3の違いとそれぞれの商品タイプについて説明されています。今後バージョン3での開発を勧めています。

アプリ内課金概要 (In-app Billing Overview)
ここでは、アプリ内にアプリ内課金(In-app Billing)を加えるために理解しておくべき、基本的なアプリ内課金の概念と特徴について説明します。

In-app Billing API

アプリはディバイスにインストールされているGoogle PlayアプリにあるAPIを使ってアプリ内課金サービスにアクセスします。Google PlayアプリはアプリとGoogle Playサーバ間の課金リクエスト(billing requests)とレスポンス(billing responses)を送ります。実際に、アプリはGoogle Playサーバと直接コミュニケーションを取ることはありません。代わりにアプリは課金リクエストをプロセス間通信によってGoogle Playアプリに送り、Google Playアプリからレスポンスを受け取ります。アプリはGoogle Play サーバ間のネットワーク通信の管理は一切しません。

アプリ内課金はGoogle Playで公開されたアプリにのみ実装することができます。アプリ内購入リクエスト( in-app purchase requests)を完了するために、Google PlayアプリはGoogle Playサーバにネットワークを通してアクセスする必要があります。


現在、Google Playはアプリ内課金APIに関して2つのバージョンを提供しています。どちらのバージョンを使うかはMigration Considerationsを参照してください。


Version 3 (Recommended)

  • Google Playからのプロダクト詳細のリクエスト、プロダクトのオーダー、ユーザのプロダクト所有に基づいたアイテムの復元などを簡単に行うため、簡素化されたAPIを通してリクエストは送られる。
  • オーダー情報は購入完了をディバイスに同期的に伝える。
  • 全ての購入は管理("managed")される。(Google Playはアプリ内プロダクトのユーザの所有を管理している。)ユーザはアプリ内アイテムのコピーを複数所有することはできない。いずれの時点でも1つのコピーだけ所有することができる。
  • 購入されたアイテムは消費することができる。消費された場合、そのアイテムは非所有状態("unowned")に戻り、Google Playから再び購入することができる。

Version 2

  • リクエストは単体APIインタフェース(sendBillingRequest)を通して送られる。
  • Google Playからのレスポンスは非同期で、Broadcast Intentの形で行われる。
  • 消費モデルは提供されない。自身で実装しなければいけません。
  • 非管理アプリ内購入アイテム (unmanaged)を管理アプリ内購入アイテム (managed) と同様サポートしている。
どちらのバージョンも幅広いAndroid端末に互換性があります。アプリ内課金Version 3はGoogle Play ストアーの最新バージョンが搭載されているAndroid 2.2以上を搭載の機種をサポートしています。Version 2も同じように互換性があります。詳細はVersion Notesを見てください。

In-app Products

アプリ内プロダクトはアプリ内からユーザに販売するために提供するデジタル商品です。デジタル商品の例は、ゲーム内の通貨、ユーザの経験を強化するアプリのアップグレード、新しいコンテンツなどが含まれます。

デジタルコンテンツを売ることだけにアプリ内課金を使うことができます。物理的商品、個人的サービス、物理的な配送を要求すものを売るためにアプリ内課金を使用することはできません。有料アプリとは違い、ユーザがアプリ内プロダクトを一度購入すると払い戻し画面は表示されません。


Google Playはコンテンツ配信の形で提供はしません。開発者にはアプリの中で売るデジタルコンテンツを配信する責任があります。アプリ内プロダクトは1つのアプリのみ明確に関連づけられています。たとえ同じ開発元であっても、他のアプリで発行されたアプリ内プロダクトを購入することはできません。


Product types

アプリの収益化の仕方に柔軟性を持たせるために、アプリ内課金は異なる商品タイプをサポートしています。全ての場合において、Google Play Developer Consoleを使って製品を定義することができます。

管理商品(managed)、非管理商品(unmanaged)、定期購買商品(subscriptions)の商品タイプをアプリ内課金で指定することができます。管理("managed")とは
Google Play がユーザのアカウントを元にアプリ内商品の所有情報を管理し記録することを示しています。一方非管理("unmanaged")とは、開発者自身で所有情報を管理しなければいけません。

APIバージョンの違いによる製品のタイプのサポートについて更に知りたい場合、以下の資料を見てください。Version2, Version3


Google Play Developer Console

Developer Consoleではアプリ内課金を実装したアプリを公開し、そのアプリから購入できる様々な商品を管理することが出来ます。

1度のみの購入や定期購入の自動更新といったアイテムを含む、
アプリに関連したデジタル商品のリストを作ることができます。各アイテムに対し、ユニーク商品ID (SKU),商品タイプ、値段、説明、商品の購入履歴をGoogle Playが管理をすべきかなどの情報を定義することができます。

また非公開のテストアプリにアクセス許可を持たせたテストアカウントを作ることができます。


商品や商品リストの設定に関してDeveloper Consoleの使い方を学ぶには、Administering in_app Billingを見て下さい。


Google Play Purchase Flow

Google Playはアプリ購入に使われるバックエンド精算サービスを使用するので、ユーザにとって一貫性のある親しみやすい購入の流れになっています。

重要:Google Play上でアプリ内課金サービスを使用する
にはGoogle Checkout Merchant のアカウントを持たなければいけません。

購入を開始するために、アプリは特有のアプリ内商品の課金リクエストを送ります。google Playは支払い形式のリクエストや認証、
ファイナンシャル取引の処理などを含む取引に関する精算の詳細をすべて管理します。

精算処理が完了すると、Google Playは注文番号、注文日時、そして支払いなどの購入の詳細をアプリに送ります。アプリはファイナンシャル取引を管理する必要はありません。それはGoogle Playによって提供されます。


The Sample Applications

アプリにアプリ内課金を統合する手助けとして、Android SDKはアプリ内で商品を売るための方法をデモした、2つのサンプルアプリを提供しています。

TrivialDrive sample for the Version 3 API

このサンプルはドライブゲームで商品購入を実装し、アプリ内課金 Version 3 APIの使い方を示しています。このアプリはアプリ内課金のレクエストの送り方、Google Playからの同期したレスポンスの管理の仕方をデモしています。また、APIを使ったアイテムの消費の記録の仕方なども紹介しています。Version 3のサンプルはアプリ内課金処理の方法と同様に自動署名認証の仕方も含まれています。

Dungeons sample for the version 2 API

このサンプルはアドベンチャーゲームのための商品と定期購買を販売するためのアプリない課金 Version 2 APIの使い方をデモしています。またデータベース、ユーザインタフェースそしてアプリ内課金の実装に使える基本的ロジックを含んでいます。

重要:アプリを公開する前にアプリのコードを難読化することを進めます。詳細情報は

Security and Designを見てください。

Migration Considerations

アプリ内課金を含んだアプリを新しく作る際やVersion 2 やそれよりも前のAPIからVersion 3のAPIにアプリ内課金の実装を移行する際に考慮するべきことは以下のとおりです。

Google PlayはVersion2とVersion3 APIどちらも同時にサポートを続ける予定です。自身のペースでVersion3に移行してください。アプリ内課金 Version 2のサポート状態の変更はGoogle Play チームから前もってお知らせします。

必要性によってどちらのAPIのバージョンを使えばいいか以下のテーブルを参照してください。
Table 1. Selecting the In-app Billing API Version for Your Project

Choose Version 3 if ...
  • You want to sell in-app products only (and not subscriptions)
  • You need synchronous order confirmations when purchases complete
  • You need to synchronously restore a user's current purchases
Choose Version 2 if ...

  • You want to sell subscriptions in your app


もし、アプリ内で商品を売っているアプリを既に公開している場合以下に注意してください。


  • Developer Consoleで前持って定義した管理アイテム("managed items")はVersion 3で使用できます。
  • Version 3 APIを使ってアイテムの購入リクエストを行う場合、既存アプリで非管理アイテム("unmanaged items")と定義されているものは管理アイテム("managed items")として扱われます。このアイテムのためにDeveloper Consoleに新しいプロダクトを作る必要はありません。このアイテムの購入のために同じプロダクトIDを使用することができます。Version2 もしくはその前のAIPを使ってその購入リクエストを作る場合、非管理アイテム("unmanaged items")としてそのまま扱われます。

2012年7月28日土曜日

[Android] Media Volume (メディアの音量)

Androidのボリュームボタンは通常、着信音量の設定になっています。
メディアの音量を変える場合には、メディアを流しているときにボリュームボタンで変えることができます。各ActivityのonCreateに以下を加えると、常にボリュームボタンをメディアの音量に設定することができます。

setVolumeControlStream(AudioManager.STREAM_MUSIC);