【android】canvasでアニメーション

scheduleAtFixedRateで周期管理して、
invalidateかpostInvalidateで画面更新するのが一般的のよう。

参考:


GraphicView.java

package com.example.myapp_sample_11_canvas_animattion;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.View;

public class GraphicView extends View {

    private int x = 0;
    private ScheduledExecutorService ses = null;
    
    //再描画のメソッド
    private final Runnable task = new Runnable(){
        @Override
        public void run() {
            // 移動処理
            x += 1;
 
            // 画面を更新
            postInvalidate();
            
            //アニメーションを停止する
            if (x > 600) {
                onPause();
            }
        }
    };
    
    //コンストラクタ
    public GraphicView(Context context) {
        super(context);
    }
    
    public void onResume(){
        // タイマーの作成
        ses = Executors.newSingleThreadScheduledExecutor();
 
        // 一定時間ごとにRunnableの処理を実行
        //   => scheduleAtFixedRate(Runnableオブジェクト , 最初の実行時間 , 実行の周期 , 値の単位(列挙型TimeUnitの値) )
        ses.scheduleAtFixedRate(task, 0L, 5L, TimeUnit.MILLISECONDS);
    }
 
    public void onPause(){
        if (ses != null) {
			// タイマーを停止する
        	ses.shutdown();
        	ses = null;
		}
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //super.onDraw(canvas);
        
        //Paint , Rectオブジェクトの生成
        Paint paint = new Paint();
        Rect rect = new Rect(100 + x, 200 , 300 + x , 400);

        //描画色の指定
        paint.setColor(Color.parseColor("#ace3d2"));
        //四角形の描画
        canvas.drawRect(rect, paint);
    }
}

追記:
onPauseを修正。アプリ終了時などにsesがnullpointerexceptionでエラーがでてしまうので、
if文にて制御した。

MainActivity.java

package com.example.myapp_sample_11_canvas_animattion;

import com.example.myapp_sample_11_canvas_animattion.R;

import android.os.Bundle;
import android.app.Activity;

public class MainActivity extends Activity {
    
    private GraphicView graphicView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        //GraphicViewのオブジェクト生成
        graphicView = new GraphicView(this);
        setContentView(graphicView);
    }

    @Override
    protected void onPause() {
        // TODO 自動生成されたメソッド・スタブ
        super.onPause();
        
        graphicView.onPause();
    }

    @Override
    protected void onResume() {
        // TODO 自動生成されたメソッド・スタブ
        super.onResume();
        
        graphicView.onResume();
    }
}

Screenshot_2013-10-28-06-12-43


【python】基礎を復習 (リスト, タプル, ディクショナリ)

それぞれ括弧の種類がちがう。

  • リスト => [ ] (角括弧)
  • タプル => ( ) (括弧)
  • ディクショナリ => { } (中括弧)

リスト

#基本
# 空リスト作成
list1 = []
list2 = list()

# 要素の含むリスト作成
list3 = [0, 1, 2]
いわゆる配列にあたる。
list1 = [1 , 2, 3]

# 他のリストのコピーを作成 (完全なコピーではない)
list2 = list(list1)

# 連番のリストを作成
list3 = range(3)        #[0, 1, 2]
list4 = range(3, 5)     #[3, 4, 5]
list5 = range(1, 21, 3) #[1, 4, 7, 10, 13, 16, 19] 3番目の引数で値の増減量を指定
rangeはfor文でも便利に使えるのでどんどん使いたいところ。

タプル

# 空タプルの作成
tuple1 = ()
tuple2 = tuple()
# 要素が1つのタプルの作成
tuple3 = (1,)
# 複数要素からなるタプルを作成
tuple4 = (0, '1', 2, [3], -4)
タプルは、変更のできない配列。

タプル / リストの操作

list  = [1, 2, 3, 4, 5]
tuple = (6, 7, 8, 9, 10)

# 要素の参照
list[1]          # 2
list[-1]         # 5 負数は末尾から参照
tuple[2]   	     # 8

# 要素の代入
list[0] = 100    # [100, 2, 3, 4, 5]
(タプルは変更できないので)要素の代入はリストのみ行える。
#タプル / リストの要素数取得
len(list)
len(tuple)
a = [1, 2, 3, 4]

#要素の取り出し
first = a.pop(0)        # 1 (a == [2, 3, 4])

#末尾の取り出し
last  = a.pop()         # 4 (a == [2, 3])

#要素の追加
a.insert(0, 5)          # [5, 2, 3]

#末尾に追加
a.append(9)             # [5, 2, 3, 9]

#末尾にリスト追加
a.extend([0, 1, 2, 3])  # [5, 2, 3, 9, 0, 1, 2, 3]

辞書 (ディクショナリ)

# 辞書 = ディクショナリ ( ≒ 連想配列)
dic = {"レモン": 100, "アボカド": 150, "椎茸": 200}


# 要素の参照
dic['レモン'] # 100

# 要素の代入
dic['アボカド'] = 300
他の言語の連想配列と同じく、キーから値の取得ができる。
dic = {"a": 100, "b": 200, "c":300}

#キーの取得
print dic.keys()    # ['a', 'c', 'b'] *順不同となるので注意

#値の取得
print dic.values()  # [100, 300, 200]

#キーの存在確認
print "a" in dic    # True

#ハッシュキーの削除
del dic["a"]


【android】Log出力を簡単に行う

公式を見る通り、
例えばLog.vなどは下のような構造になっていて、

Log.v (String tag, String msg);
第一引数、第二引数、ともにString型を引数として渡す必要が有る。

ただ、場面に寄っては第二引数にString型以外のものを渡したい時がでてくると思う。
そんなとき、簡易的にLog出力を行う方法がある。
for (int i = 0; i < 100; i++) {
    //ランダムオブジェクトの生成
    Random rnd = new Random();
    //ランダム値
    int ran = rnd.nextInt(i * i + 1);
    
    Log.v("ランダム値" , "" + ran);
}
7行目のLog.vでは、int型のranを出力しようとしているので、
本来はキャストしなければならない。
が、空の文字列「””」を付加することで、
簡易的にString型として渡すことが出来る。
byte   byteEx   = 127;
short  shortEx  = 32767;
int    intEx    = 3;
double doubleEx = 2.3;
float  floatEx  = 1.40282347F;
long   longEx   = 1223372036854775807L;

Log.v("byte型"   , "" + byteEx);     //byte型: 127
Log.v("short型"  , "" + shortEx);    //short型: 32767
Log.v("int型"    , "" + intEx);      //int型: 3
Log.v("double型" , "" + doubleEx);   //double型: 2.3
Log.v("float型"  , "" + floatEx);    //float型: 1.4028234
Log.v("long型"   , "" + longEx);     //long型: 1223372036854775807
int型以外もこの方法は有効。


【python】基礎を復習 (変数 , 演算 , 文字列)

タイトル通り。(なんか順番がおかしなかんじだけど….。)
ちなみにこちらを参考に書いてます。

環境:python2.7.5

変数

a = 'hoge'
a = 1
a = 5.9
num = 1 + 1j #jは虚数
文字列は「’」か「”」で囲む。
整数、少数もok。
宣言や型は必要ない。

演算

num = 1 + 1 
num = 1 - 1
num = 1 * 2
num = 5 / 2    # 整数のみの除算 => 整数で返る
num = 5.0 / 2  # どちらかが少数の除算 => 少数で返る
num = 5 % 2    # 剰余
num = 2 ** 3   # 累乗
4行目、5行目は重要そう。
i += 1 #インクリメント
i -= 1 #ディクリメント
++演算子はなし。上記のみの書き方になる。
#論理演算
a or b  # aが偽ならb 、そうでなければa
a and b # aが偽ならa 、そうでなければb
not a   # aが偽ならTrue 、そうでなければFalse
真偽を返すのはnotのみであるので注意。

文字列

#基本
a = 'aaa'
b = "bbb"

#改行を含んだ文字列
c = '''ccc
ccc
ccc'''
#ダブルクォートでもok
d = """ddd
ddd
ddd"""
改行はエスケープシーケンス(\n)でもよい。
# coding: UTF-8
# 日本語のコメントを書く場合は、UTR-8に設定する
print u"お昼はうどんを食べます!"
2系はunicodeサポートしているので日本語が使える。print文にuをつける。
*一行目の宣言はかならずファイルの先頭に記述する。

文字列処理いろいろ

# 文字列フォーマット
# 基本
str = "{0} : {1} + {2} = {3}"
print str.format("足し算" , 8, 0.5, 8 + 0.5) 
# 足し算 : 8 + 0.5 = 8.5

# 辞書によるformat
str = "名前 : {0[name]}, 性別 : {0[sex]}"
print str.format({"name":"tanaka", "sex":"male"}) 
# 名前 : tanaka, 性別 : male

str = """木材としては、日本国内でも「{0}」という名称で扱われる。(中略)
1660年から1720年にかけ、ヨーロッパ市場ではイギリスデザインや{0}種の製品が大きな人気を博し、
ヨーロッパ家具の歴史では「{0}の時代」と呼ばれるほど持て囃された。"""
print str.format("ウォールナット")

# 木材としては、日本国内でも「ウォールナット」という名称で扱われる。(中略)
# 1660年から1720年にかけ、ヨーロッパ市場ではイギリスデザインやウォールナット種の製品が大きな人気を博し、
# ヨーロッパ家具の歴史では「ウォールナットの時代」と呼ばれるほど持て囃された。
文字列フォーマットによる置き換え。
(.formatメソッドの他に「%演算子」に置き換えも可能だが、こちらは廃止予定だそう。)
# 長さ(文字数)
#   =>  「 」(スペースもカウント)
str = 'SUPER GREAT SPECIAL CONTENTS'
length = len(str)
print length    # 28

str = '日本語むつかしい'
length = len(str)
print length    # 24

str = u'日本語むつかしい'
length = len(str)
print length    # 8
マルチバイト文字を扱うときは注意。
「u」でunicode宣言してるか否かで結果が異なる。
str1 = 'aaa'
str2 = 'bbb'

# --結合--
join1 = str1 + str2
print join1 # aaabbb
 
#(区切り文字を指定して)結合
join2 = ','.join([str1, str2])
print join2 # aaa,bbb (「,」で区切られた文字列が取得できる )
 
# --分割--
str = 'aaa bbb  ccc'
record1 = str.split()
print record1 # ['aaa', 'bbb', 'ccc'] デフォルトは半角スペースで分割
 
#(区切り文字を指定して)結合
record2 = str.split(',')
print record1 # ['aaa', 'bbb', 'ccc']
 
# --切り出し--
# [start:stop]の形で指定して切り出し
str = '0123456789'
substr1 = str[:3] # 0~stop-1を切り出し
substr2 = str[3:6] # start~stop-1を切り出し
substr3 = str[6:]  #start~末尾を切り出し
 
print substr1 # 012
print substr2 # 345
print substr3 # 6789
 
# --検索--
str = 'abcdefg'
result = str.find('cd') # 見つかった場合はその位置、見つからなかった場合は-1が返る
print result # 2


【python】基礎を復習 (if文 , for文 , while文)

随分昔にふと「なんかpython触ってみたい、流行ってるらしいし」などと思ったことがあって、
そのときは結局すぐ挫折したのだけど、
最近また現実逃避の道具として復習し始めてる。

といっても、何か目的があるわけでもなく、また完全な独習なので遅々としてるけど…。
せっかくなので、備忘録として基礎をまとめていこうと思う。

とりあえずタイトル通り。最初はif文とfor文while文などのループ処理。

共通しているのは、

  • ・{}など括弧は使わない、インデントでブロック扱いとなる
  • ・条件文の後にはコロン(:)を付ける
といったところ。

*なお環境は2.7.5です。
3系と2系でpythonはかなり差異があるそうなので、
予め「python -V」でバージョンを確認した方が良いです。

if文

# 基本
n = 5

if n < 30:
    print "ok"
普通です。
# if文色々
score = 64

if score >= 80:
    print "great!"
elif 80 > score > 50:
    print "ok"
else:
    print "too bad.."
注意するのは、else ifはなくelifのみという点。
score = 40
print "ok" if score >= 80 else "too bad..."
条件演算子( ≒ 三項演算子)でも書ける。

for文

#基本
for i in [1, 3, 6, 7, 9]:
    print i
1
3
6
7
9
…と表示される。
for i in [1, 3, 6, 7, 9]:
    sum += i
else:
    print sum
else:も付けられる。最後に実行される。
#rangeで簡単にループが作れる
for i in range(3):
    print i
0
1
2
…と表示される。
通常のfor文っぽくて便利。
#入れ子も可能
for i in range(10):
    if i % 3 == 0:
        print "hoge"
    print i
else:
    print "\nfin...."
3の倍数のみhoge表示。
#辞書のループ
a = {"Tom":100, "Bob":200, "Elly":500}

#keyとvalue両方ループ表示
for k , v in a.iteritems():
    print "key: %s value: %d" % (k, v)

#keyのみループ表示
for k in a.iterkeys():
    print k

#valueのみループ表示
for v in a.itervalues():
    print v
辞書 = ディクショナリー(連想配列みたいなもの)を利用したfor文。  

while文

# 基本
n = 0

while n < 10:
    print n
    n += 1
普通ですね。
    #無限ループ。1かTrueを使うのが慣例らしい
    while 1:  
     print "hoge"  
当然breakするか強制終了するしか抜けられない。
# continueで3のときだけ抜ける
while n < 10:
    if n == 3:
        n += 1
        continue
    print n
    n += 1
else:
    print "end"
ここでのelseはwhileがfalseとなったときに実行される。
なので、下の「end」は表示されない。
#breakはelseも表示されない
while n < 10:
    if n == 3:
        n += 1
        break
    print n
    n += 1
else:
    print "end"

思ったこととか

インテントブロックは慣れたら見やすい気がしてきた。