Android勉強中

まずは初歩から…

ということで、初歩からわかるAndroid最新プログラミングを購入して順々にNexus Sで動かしながら勉強中。
この本すごくいいと思ったんだけど、それは主に以下の2点。

  1. サンプルのプログラムが結構魅力ある。短いコード行数なのに結構楽しげなアプリができるので、早く自分でも何か作ってみたくなる
  2. 説明が丁寧。しかもその説明が主にコード中に描いてある。あまりコードに紙面を割いてる本は身構えちゃう事が多いんだけど、これはソースでの説明が丁寧なので、頭からまっすぐ読んでいけるメリットが大きい。

で、今マルチタッチのところまで読んだんだけど、ちょっと気になる点が…
本の通りにコーディングしても、どうもマルチタッチの時の画面の反応が悪い。気になったのはonTouchEvent()内のここ

// タッチ数を取得
int pointer_count = event.getPointerCount();

// イベントの種類で条件分岐
// タッチされた指がスライドされたことを表すイベント
if (action_type == MotionEvent.ACTION_MOVE)
{
    // MOVEイベントの場合のみ、処理の重さに応じて
    // 処理がスキップされヒストリーに保存されている
    // ヒストリー数(過去のイベント情報をどれだけ保存しているか)を取得
    int history_count = event.getHistorySize() / pointer_count;

    // ヒストリーはインデックスが若いものほど古いので、古い順に処理する
    for (int i = 0; i < history_count; i++)
    {
        // 2箇所分のタッチイベントを検出する
        for (int j = 0; j < 2; j++)
        {
            int idx = event.findPointerIndex(j);

            // タッチされていなければ、findPointerIndexが-1を返す
            if (idx >= 0)
            {
                // タッチ座標を取得
                int x = (int) event.getHistoricalX(idx, i);
                int y = (int) event.getHistoricalY(idx, i);
                mainView.setTouchXY(j, x, y);
                mainView.setTouchFlag(j, true);
            }
            else
            {
                mainView.setTouchFlag(j, false);
            }
        }
    }
}

これ、こんな感じにしないといけないんじゃないかなぁ…

if (action_type == MotionEvent.ACTION_MOVE) {
    // historyに追いやられてるTouchイベントを処理する
    for (int h = 0; h < event.getHistorySize(); h++) {
        for (int j = 0; j < 2; j++) {
            int idx = event.findPointerIndex(j);
            if (idx >= 0) {
                int x = (int)event.getHistoricalX(idx, h);
                int y = (int)event.getHistoricalY(idx, h);
                mainView.setTouchXY(j, x, y);
                mainView.setTouchFlag(j, true);
            } else {
                mainView.setTouchFlag(j, false);
            }
        }                    
    }
    // 今回のTouchイベントを処理する
    for (int j = 0; j < 2; j++) {
        int idx = event.findPointerIndex(j);
        if (idx >= 0) {
            int x = (int)event.getX(idx);
            int y = (int)event.getY(idx);
            mainView.setTouchXY(j, x, y);
            mainView.setTouchFlag(j, true);
        } else {
            mainView.setTouchFlag(j, false);
        }
    }
}

Documentはちゃんと読めてないけど、実機の挙動見る限り

  • onTouchEventが呼ばれた時、最新のTouchイベントはHistoryに入ってない。つまり指をゆっくり動かしてて余裕ある時はHistoryはずっと0件。最新のTouchイベントも処理しないといけない
  • event.getHistorySize()で帰ってくるサイズをevent.getPointerCount()で割る必要はなさそう。History1個の中にPointerCount分の情報入ってる

っていう風に見えたのでそこを直しました。間違ってたらごめんなさい。

ただ今のところそこだけでコードの品質も高そう。本屋でいくつかAndroidの入門書を立ち読みした限り、最初に読む一冊としては一番良い印象でした。

続きを読む Android勉強中