2013年4月25日木曜日

PopupMenuの内容を動的に設定

結局使わなかったがAPI level 11(HONEYCOMB)から利用可能になったPopupMenuの内容を動的に変えようと思ったらあまり情報がなかったので書いておきます。

表示はこんな感じ

ソースはこんな感じ

PopupMenu popup =new PopupMenu(MainActivity.this, findViewById(R.id.button1));
popup.getMenu().add(1, 1, 1, "TEST1");
popup.getMenu().add(1, 2, 2, "TEST2");
popup.getMenu().add(1, 2, 3, "TEST3");
popup.show();
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
  @Override public boolean onMenuItemClick(MenuItem item) {
    Log.v("LOG", "Menu:" + item.getGroupId() + "," + item.getItemId());
    return false;
  }
});

なぜ使わなかったのかというと表示位置がviewのアンカーでの指定しか出来ず、任意の位置に出せなかったから。
任意の位置に出せる方法を知ってる人がいたら教えてくださーい

2013年4月24日水曜日

Androider+6月号に"間取りー図"が掲載されたー

アンドロイダー+(プラス)6月号(4月19日発売)に間取りー図が掲載されましたー



自分の作ったアプリが本に載るっていうのは一つの目標でしたので、すごくうれしいですね

2013年4月23日火曜日

ダイアログのボタンなどに表示する文字列

アプリではよくダイアログを表示して○○でよろしいですか?"OK" or "Cancel"とかよく表示することがあると思います。



ここで表示する"OK"等の文字列はリソースで用意したR.string.*とか、直接コードに書いている方もいるでしょう。
しかし、OKやCancelなどの一般的な文言はAndroid本体のリソースであるandroid.R.stringを使うべきかと思います。
なぜかというとandroid.R.stringはAndroidが対応する全ての言語に対応しているからです。SDKにあるリソースのフォルダを見てみるとこんな感じ。



全ての言語に対応したフォルダがあります。
これらはOS標準のアプリや設定で使用されますので、それらとの統一を図る意味でもこちらを使用したほうがいいと思います。

2013年4月22日月曜日

画像の回転ロジック

PhotoRouletteでは12個の画像を回転させていますが、ルーレットに使う画像がたとえ1個でも100個でも大丈夫なように作っています。
実際には画像をArrayList<Bitmap>にすべて入れて下から順番に左回りに回転させながら描画しています。
 このとき回転角が360/12を超えたときリストから描画するindexに+1して12枚に足りなければ0から繰り返し12枚より多ければ2~13を表示というようにしていきます。
ソースは以下のような感じ。

//回転角+1
angle += 1f;
//回転角が360/12を超えたら描画開始indexを1つ増やす
if (angle >= (360f / 12f)) {
    angle = angle - (360f / 12f);
    start++;
    //ルーレットの画像数を超えたら0に戻す
    if (start > roulette.images.size()) { start = 0;}
}
Matrix mat = new Matrix();
//描画開始indexをセット
int index = start;
for (int i = 0; i < 12; i++) {
    mat = new Matrix();
    //画像中心を中心点にして回転
    mat.postRotate(((360f / 12f) * i) - 180f + angle, width / 2f, height / 2f);
    canvas.drawBitmap(roulette.images.get(index), mat, paint);
    index++;
    //ルーレットの画像数を超えたら0に戻す
    if (index >= roulette.images.size()) { index = 0;}
}

このルーレットを回すロジックはいろんなやり方で実装できると思いますが、結果が同じであればどんなやり方でもいいと思います。
こんなこというと怒られますが、今時多少効率の悪い書き方をしても影響が出る場面は少ないですし、よく後から見て直しやすく再利用しやすいようにとか言いますが、こういう汎用的ではない処理は実際のとこ見ることも再利用することも極々稀で多くの場合は1から作った方が古いのよりいい物が出来ます。

2013年4月19日金曜日

カメラ画像からの透過画像作成

今回のアプリPhotoRouletteでちょっと手こずった透過画像の作成です。






このようなカメラから取得した画像(実際はもっと大きいです)を





ルーレットで使用するためこのように台形状に切り出して透過画像を作成したい


今回とった手法は以下のような感じ
  1. Bitmap.createBitmapでカメラ画像から必要な大きさ分を切り出して作成
  2. もう一回Bitmap.createBitmapで切り出した画像から編集用Bitmapを作成。
    この時注意することとして、createBitmapのconfig指定をBitmap.Config.ARGB_4444かARGB_8888RGにする。RGB_565にしてしまうと透過しない。
  3. paint.setColor(Color.TRANSPARENT)を指定
  4. paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.CLEAR))を指定
  5. drawPathで画像の左右の透過したい三角の部分を塗りつぶします。
ソースとしては以下

 //切り出し画像作成
 Bitmap clip = Bitmap.createBitmap(image, (int)(image.getWidth() * 0.2), (int)((image.getHeight() - (image.getWidth() * 0.5)) / 2), (int)(image.getWidth() * 0.6), (int)(image.getWidth() * 0.5));
 //透過編集用画像作成 
 Bitmap edit = Bitmap.createBitmap(clip.getWidth(), clip.getHeight(), Bitmap.Config.ARGB_8888);
 Canvas canvas = new Canvas(edit);
 canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
 canvas.drawBitmap(clip, 0, 0, paint);
 //透過用Paint作成
 Paint paint = new Paint();
 paint.setColor(Color.TRANSPARENT);
 paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.CLEAR));
 paint.setStyle(Style.FILL);
 //左下透過部分
 Path path = new Path();
 path.moveTo(0, 0);
 path.lineTo(0, edit.getHeight());
 path.lineTo(edit.getHeight() * 0.265f, edit.getHeight());
 path.lineTo(0, 0);
 canvas.drawPath(path, paint);
 //右下透過部分
 path = new Path();
 path.moveTo(edit.getWidth(), 0);
 path.lineTo(edit.getWidth(), edit.getHeight());
 path.lineTo(edit.getWidth() - (edit.getHeight() * 0.265f), edit.getHeight());
 path.lineTo(edit.getWidth(), 0);
 canvas.drawPath(path, paint);

2013年4月18日木曜日

Androidアプリの設計

さて、作りたいアプリが決まったら設計に入ります。
これは人によって違うでしょうが、私の場合アプリに必要な画面を紙に全部書いていきます。
規模によっても違いますが、いままで作ってきたのではこれがそのまま設計書になります。
今回のPhotoRouletteの場合下のような感じ、大変汚い殴り書きで恥ずかしい…
画面を書いたらその中で必要な機能を書いておきます。
そのあとはこの中で必要になりそうなクラスで主要なデータになるやつと複雑なやつは
大雑把にクラス設計をしておきます。
今回の場合はルーレットのデータになるクラスを作りました。

public class Roulette {
 String name = "";
 Date date = null;
 int count = 0;
 Bitmap image = null;
 ArrayList<Bitmap> images;
}

それほど複雑なアプリでなければこれで私の場合これで設計完了です。

2013年4月17日水曜日

Androidアプリの効果音

今回のPhotoRouletteで使っている効果音は二つ、ルーレット開始と決定時だけですが、こちらの効果音を利用させてもらってます。

ザ・マッチメイカァズ2nd
現在更新は止まっているようですが、約1600種類もの効果音があります。
ここにあるファイルはwavファイルなのでoggに変換してres\raw\フォルダの中に入れてSoundPoolを利用して使っています。
効果音なんかの場合レスポンスがいいSoundPoolを使ったほうがいいと思います。

その他フリーの効果音・BGMはこちらがとても参考になります。
効果音・BGMのフリー音素材リンク集 - NAVER まとめ