2011年8月アーカイブ

Android 標準のアニメーション補間クラス(Interpolator)の名前と効果がわかりづらかったので、グラフ化してみました。

グラフ化にあたっては、入力を 0.00 から 1.00 まで0.01 ずつ変化させ、プロットしています。

グラフ化してみると、AnticipateOvershootInterpolator のように、

出力の範囲(0.00~1.00)を飛び越えているものもあり、興味深いですね。

※@esmasui さんが作ってくださったアニメーション「Android Interpolations」(要Chrome?)が わかりやすいです!


AccelerateDecelerateInterpolator

core/java/android/view/animation/AccelerateDecelerateInterpolator.java

AccelerateDecelerateInterpolator.png

 

AccelerateInterpolator

core/java/android/view/animation/AccelerateInterpolator.java

AccelerateInterpolator.png

 

AnticipateInterpolator

core/java/android/view/animation/AnticipateInterpolator.java

AnticipateInterpolator.png

 

AnticipateOvershootInterpolator

core/java/android/view/animation/AnticipateOvershootInterpolator.java

AnticipateOvershootInterpolator.png

 

BounceInterpolator

core/java/android/view/animation/BounceInterpolator.java

BounceInterpolator.png

 

CycleInterpolator

core/java/android/view/animation/CycleInterpolator.java

CycleInterpolator.png

 

DecelerateInterpolator

core/java/android/view/animation/DecelerateInterpolator.java

DecelerateInterpolator.png

 

LinearInterpolator

core/java/android/view/animation/LinearInterpolator.java

LinearInterpolator.png

 

OvershootInterpolator

core/java/android/view/animation/OvershootInterpolator.java

OvershootInterpolator.png

 

ソースコード

グラフ化にあたっては、Android 上で以下のようなソースコードを実装しました。

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.WHITE);
    
    Paint paint = new Paint();
    paint.setColor(Color.BLUE);
    paint.setAntiAlias(true);
    
    OvershootInterpolator interpolator = new OvershootInterpolator();
    
    PointF points[] = new PointF[100];
    for (int i = 0; i < 100; i++) {
        points[i] = new PointF();
        points[i].x = i;
        points[i].y = 100 - interpolator.getInterpolation((float) i / 100) * 100;
    }
    
    canvas.save();
    {
        PointF offset = new PointF(50.0f, 150.0f);
        canvas.translate(offset.x, offset.y);
        for (int i = 0; i < 99; i++) {
            canvas.drawLine(points[i].x, points[i].y,
                    points[i + 1].x, points[i + 1].y, paint);
        }
        Paint framePaint = new Paint();
        framePaint.setColor(Color.BLUE);
        framePaint.setAntiAlias(true);
        framePaint.setStyle(Style.STROKE);
        canvas.drawRect(0, 0, 100, 100, framePaint);
    }
    canvas.restore();
}

 

備考

  • 上記補間クラスを用いた実際のアニメーションについては、ApiDemos/Views/Animation/Interpolators で確認できます
  • Interpolator インタフェースを実装したクラスを作成すれば、好きな補間クラスを作成できます
  • ちなみに ActionScript を触っていた頃は下図のような補間関数を実装した Tweener ライブラリを使っていました
    (誰か、Android にも移植しないかな^^; Android 標準だと少ないですもんね。。。)

tweener.png

 

追記

Twitter API の中でも一、二を争うであろう面白い API である UserStream(ユーザーストリーム)を使ってみました。

Android 上でも Twitter4J ライブラリーを使用すると、簡単に実装できます。

以下、twitter4j-android-2.2.4 で確認しました。

 

Twitter4J で UserStream を呼び出す手順

1. TwitterStreamFactory をインスタンス化する

 ※コンストラクターには、OAuth 情報をセットした ConfigurationBuilder インスタンスを渡す

2. TwitterStream をインスタンス化する

 ※1 の TwitterStreamFactory インスタンスから取得できる

3. UserStream 受信時に応答する(UserStreamListener)リスナーを実装する

 ※必要な onXXX() をオーバーライドする

4. TwitterStream に UserStreamListener を実装したインスタンスを設定する

5. TwitterStream#user() を呼び出し、ユーザーストリームを開始する

6. UserStream 受信時、3 で実装したメソッドが呼び出されるので必要な処理をする

 

サンプルソースコード

http://code.google.com/p/adakoda-android-sample/source/browse/trunk#trunk%2FTwitter4JUserStream

package com.adakoda.android.twitter4juserstream;

import twitter4j.Status;
import twitter4j.TwitterStream;
import twitter4j.TwitterStreamFactory;
import twitter4j.UserStreamAdapter;
import twitter4j.conf.Configuration;
import twitter4j.conf.ConfigurationBuilder;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;

public class Twitter4JUserStreamActivity extends Activity {

    private MyUserStreamAdapter mMyUserStreamAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mMyUserStreamAdapter = new MyUserStreamAdapter();

        // ここは別途OAuth認証して情報を取得する。。。
        String oAuthConsumerKey = "あなたのTwitterクライアントで取得したものに置き換えてください";
        String oAuthConsumerSecret = "あなたのTwitterクライアントで取得したものに置き換えてください";
        String oAuthAccessToken = "あなたのTwitterクライアントで認証したユーザーの情報に置き換えてください";
        String oAuthAccessTokenSecret = "あなたのTwitterクライアントで認証したユーザーの情報に置き換えてください";

        // Twitter4Jに対してOAuth情報を設定
        ConfigurationBuilder builder = new ConfigurationBuilder();
        {
            // アプリ固有の情報
            builder.setOAuthConsumerKey(oAuthConsumerKey);
            builder.setOAuthConsumerSecret(oAuthConsumerSecret);
            // アプリ+ユーザー固有の情報
            builder.setOAuthAccessToken(oAuthAccessToken);
            builder.setOAuthAccessTokenSecret(oAuthAccessTokenSecret);
        }

        // 1. TwitterStreamFactory をインスタンス化する
        Configuration conf = builder.build();
        TwitterStreamFactory twitterStreamFactory = new TwitterStreamFactory(conf);
        // 2. TwitterStream をインスタンス化する
        TwitterStream twitterStream = twitterStreamFactory.getInstance();
        
        // ユーザーストリーム操作
        {
            // 4. TwitterStream に UserStreamListener を実装したインスタンスを設定する
            twitterStream.addListener(mMyUserStreamAdapter);
            // 5. TwitterStream#user() を呼び出し、ユーザーストリームを開始する
            twitterStream.user();
        }
    }
    
    // 3. UserStream 受信時に応答する(UserStreamListener)リスナーを実装する
    class MyUserStreamAdapter extends UserStreamAdapter {

        // 新しいツイート(ステータス)を取得する度に呼び出される
        @Override
        public void onStatus(Status status) {
            super.onStatus(status);
            // 6. UserStream 受信時、3 で実装したメソッドが呼び出されるので必要な処理をする
            // サンプルログ出力
            Log.v("Twitter4JUserStreamActivity", status.getText());
            // ここではサンプルとして通知発行メソッドを呼び出している
            Twitter4JUserStreamActivity.notify(Twitter4JUserStreamActivity.this,
                    status.getId(), status.getText(),
                    status.getUser().getId(), status.getUser().getScreenName());
        }
    }

    // おまけ:ツイート内容から通知を発行する
    private static void notify(Context context, long statusId,
            String statusText, long userId, String userScreenName) {
        // NotificationManager取得
        NotificationManager nm = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        // Notification構築
        Notification notification = new Notification(R.drawable.icon,
                statusText, System.currentTimeMillis());
        // 通知をタップした時に起動するペンディングインテント
        PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
                // ウェブのURLを処理するアプリを起動する
                new Intent(Intent.ACTION_VIEW,
                        // 通知で表示されているツイートのURL
                        Uri.parse("http://twitter.com/#!/" + userId + "/status/" + statusId)),
                        Intent.FLAG_ACTIVITY_NEW_TASK);
        // 通知に表示する内容を設定
        notification.setLatestEventInfo(context, statusText, userScreenName, contentIntent);
        // 通知を発行
        nm.notify(0, notification);
    }

}

 

実行結果

Notification.png

新しいツイート(ステータス)を受信するたびに、リアルタイムで通知が飛びます^^;

※上記のように通知領域を表示したままだと、どんどん入れ替わります

 

また、通知をタップすると、URL を処理できるアプリで表示できます(以下は Twicca)。

Intent.png

 

注意点

UserStream 受信時に呼び出されるリスナーは、メインスレッドとは別のスレッドから呼び出されているため、

UI 操作を行う場合には、handler#post() などから呼び出す必要があります。

 

あわせて読みたい

1

2016年8月

  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31