2013年3月6日水曜日

ボタンの上で画像をクルクルさせる

友達に見せてソレどーやるの!??と言ってもらえて嬉しかったのをメモ(*'ω'*)♫

これはキャラクター選択画面でボタンを押すと
星の輪っかがクルクル回るという仕掛けです。

選択している方のボタンだけに出るので、Viewの表示・非表示も使ってます。

これはいろんなことに応用できるので知らなかった方はぜひ使ってみてください★
ペンギンさんを作ったのは私じゃないので、その内差し替えるかも。
まぁ多分作者さんは優しい方なので気にしないでしょう(*´ω`*)
このヒット数ならなおさらw

月曜日に報告をしなさい、私。('ω')ノ

まずViewの重ね方

layoutファイルですが、
普通にLinearLayoutやTableLayoutの中でボタンを置きたいところに
ボタン→重ねるImageの順に書いてRelativeLayoutで囲みます。
        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

                <ImageButton
                    android:id="@+id/btn_Penguin"
                    android:layout_width="130px"
                    android:layout_height="130px"
                    android:background="@drawable/penguin"/>
                <ImageView
                    android:id="@+id/iv_circle"
                    android:layout_width="130px"
                    android:layout_height="130px"
                    android:background="@drawable/circle"/>
            </RelativeLayout>

RelativeLayoutはその範囲の中で左上を起点にViewを重ねてくれるLayoutです。
文字を重ねたり、といろいろ便利。
私は自作のアプリに大体1回は出てくるほど気に入って使ってます。

続いてViewの表示・非表示

ACTIVITY側で行います。
使い方は簡単で、ImageViewで用意した変数に
「.setVisibility(View.INVISIBLE);」(非表示)
           と
「.setVisibility(View.VISIBLE);」(表示)

で切り替えるだけです。
まずImageButtonやImageViewを宣言したあとに、
私はLayoutファイルで画像の指定をしているので
○○.setVisibility(View.INVISIBLE);とImageViewの方を非表示にします。

続いてButtonを押されたら
       a_circle.setVisibility(View.VISIBLE);
       b_circle.setVisibility(View.INVISIBLE);
もう片方は消すという処理を、書いておきます。

こうすると、もう一つが選ばれたときペンギンの方は再度消えるという仕組みです。

お次はクルクル回すアニメーション処理

まずanimフォルダにanimationを定義したファイルを作ります。
res>anim>好きな名前.xmlで作成。私はrotate.xmlという名前で作りました。

内容はこんな感じ

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
     android:duration="200"
     android:fromDegrees="0"
     android:toDegrees="360"
     android:pivotX="50%" 
     android:pivotY="50%"

     android:interpolator="@android:anim/linear_interpolator"
     android:repeatCount="2"/>

 オレンジ部分が起点をどこにするか、というものなのだけど、
今回ボタンと同じ大きさのViewを用意しているので
50% ・ 50%で丁度真ん中、という感じです。

durationはms。これは0.2秒で1回転します。
2回回ったら終了、という設定です。

アニメーショんはJavaファイルでも指定が必要です、が超簡単。
       Animation anim = AnimationUtils.loadAnimation(this, R.anim.rotate);
       iv_circle.startAnimation(anim);

これをボタン押した処理の中でa_circle.setVisibility(View.VISIBLE);の後に追加!
それだけです。

知識がそんな無くてもAndroid用に用意されている物だけで
結構かわいく&華やかになるものですなぁ(*´ω`*)

そして解説時は何故か「です、ます調」になる私。


2013年3月3日日曜日

アプリの終了の仕方

メモメモ

現在作ってるゲームがACTIVITYを複数枚行き来していて、
その内のひとつがSurfaceViewを使っている。
終了させようとするとヌルポエラーがっ(´・ω・`)

検索して
Activityを終了させるのはfinish()
全体を終了させるのはmoveTaskToBack(true);

プロセスまで終了させるのは
android.os.Process.killProcess(android.os.Process.myPid());
↑でも非推奨らしい。

と分かった。でも、どの方法を試してもエラーが出るー。

と困ってたらThreadの終了の仕方と、
他ACTIVITYでの処理の仕方が間違ってたー。

thread = null
は終了方法でなく「もういらない宣言」なんだって。
そうだったのかー('ω')

SurfaceViewを入れてるACTIVITYのonPauseに
  public void onPause(){
     super.onPause();
     ActionView.finishLoop();
   }

 と書いてLoop終了メソッドを呼び出す。

そのループ終了のメソッドは
 public static void finishLoop() {
   synchronized (thread) {
    // ループを抜ける
    looper = false;
  }
   try{
     // スレッドの終了を待つ
     thread.join();
   } catch( InterruptedException ex ){

 
     Thread.currentThread().interrupt();
   }
 }

 としました。
参考にさせて頂いたどこかの企業様のBlogがURL分からなくなってしもた。
見つけたら追記しまする。

それで各ACTIVITYに戻るボタンを押したらダイアログを表示させるように。
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode==KeyEvent.KEYCODE_BACK){
         new AlertDialog.Builder(Activity.this)
         .setMessage("終了してもいいですか?")
         .setCancelable(false)
         .setPositiveButton("はい",new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                MySurfaceView.finishLoop();
                moveTaskToBack(true);
             }})
            
         .setNegativeButton("いいえ", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
           dialog.cancel();}}).show();
          return true;
        }
        return false;
    }
SurfaceViewを含んでいないActivityにはmoveTaskToBack(true);だけ書いた。
(最初は全部にMySurfaceViewにあるthreadを終了させる文も書いてしまったので、
 もうないよ、とNullPointerが出ていたようです。。。。恥ずかしい。)

これで私の望み通りに完成!
うれしー(*´ω`*)

でもどうやら面倒がってstatic変数を多用してしまったせいか
メモリを使いすぎかもしれない・・・・・。

だもんで、現在清書も兼ねて、なるだけstatic変数を使わないよう移行中!
来週中には出来そうです(∩´∀`)∩~♥わーい