fc2ブログ

    Androidのライブ壁紙でアナログ時計



    ■Androidのライブ壁紙でアナログ時計

    アナログ時計自体はウィジェットとか使えば楽ちんで出来るんだけど、
    ライブ壁紙でも作りたいよね。よね。
    1回つくっとけば応用もできそうだし、よし作ろう。

    ということで作り始めたはいいが、どちらかというとJAVAのお話にも
    なるので、それ系で調べてみると素敵な参考サイト発見。(相変わらずの他力本願)

    参考サイト:
    http://d.hatena.ne.jp/yatcho/20090423/1240477532

    きっと色々とやり方はあるんだろうけど、ここが一番わかりやすかった。
    このサイトでやってるのをライブ壁紙用に改造した↓まずはライブ壁紙の本体。




    つづいて、時計の計算クラス。これはほぼそのまま↓。



    解説: Clockクラスで計算した座標をもとに、Clock01のライブ壁紙クラス側で描画してます。
    Clockの座標計算のあたりは見ておくと勉強になります。特に僕のような初心者には。
    ここまでできてれば、あとは秒針とかの画像を変えればそれなりに良いのできるんでないかい?
    ありがたや~
    あ、画像サイズは今は480,800が入ってるから適宜変えて下さい。

    ちゃんとできてたら、こんな感じで見えるはず。↓

    device-2011-10-22-103841.png
    秒針が動いていたらOKです。
    あと、Manifestとかは通常のライブ壁紙と同様に設定してください。
    スポンサーサイト








    LiveWall(ライブ壁紙)でタッチの座標がずれる




    ■LiveWall(ライブ壁紙)でタッチの座標がずれる


    ライブ壁紙にPreferenceを設定したころ、困った問題が…

    「Preferenceで設定変更して、SurfaceViewを
    再描画するとタッチの座標がずれる!」


    というもの。別にびっくりマーク付けるほどのもんでもないけど、
    うっかり見落としそうになったので。
    座標がずれるということは、widthとheightの設定が上手くいってないからじゃね?
    と思い調べてみると、Engine内でのonSurfacechangedとか、
    Thread内でのinitializeとか、renderer内でのonSurfacechangedとか、

    まー、ことあるごとにwidthとheightがしゃしゃり出てくる

    ということで、それぞれに

    Log.i(getClass().toString(),"onSurfaceChanged+windowWith" + width);


    みたいにログをしかけてデータをとる。
    獲物をしとめる漁師のように地道に大きさを見ていくと、所々で
    おかしな数字が…。
    それらの参照するwidthやheightの変数をしっかり作ってあげることで解消できました。


    いやー、いま思うとなんてことないんだけど、最初タッチしても無反応だから焦った。




    LiveWallPaperとOpenGLとonSharedPreferenceChanged




    ■LiveWallPaperとOpenGLとonSharedPreferenceChanged

    さて、無事OpenGLをつかってライブ壁紙を作れたわけですが、
    1個作ったら俄然欲が出てきて
    「壁紙変えてぇ」
    「パーティクルの数変更してぇ」
    となるわけです。バッテリーのことも考慮して、負担へらせる
    設定変更もできたらなと。

    お手軽な設定変更方法といえば、SharedPreferencesを使った方法があります。

    PreferenceActivityを継承したプリファレンス用のクラスを作成し、
    実装するわけですが、ここでハマった点を説明(というか自分用メモ)

    ・onSharedPreferenceChanged()を実装する場所
    まずそこからして分からなかったおバカさんな僕ですが、試行錯誤の末に
    ライブ壁紙の場合はエンジンを継承したクラス(参考本の例だとGLengineクラス)
    に実装します。

    ライブ壁紙に設定画面を追加する
    ↑こちらの内容を100万回ほど参考にしてなんとか実装したのだけれど、困ったことが。
    リンク先でも言及されているが、設定変更後は通常drawframe()などで再描画を行い
    変更を反映する必要がある。
    ところがところが、OpenGLで作った場合そのdrawfameメソッドみたいなのがないのです。
    いやあるんだけど、まずは↓を見てみよう。


    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
     String wall_list = sharedPreferences.getString("list_key","wall001"); //preference.xmlに設定したキーと初期値
     if(wall_list.equals("wall002")){ //処理いろいろ。ここではリストから選択して壁紙変更
     mWall = R.drawable.wall002;

     }else if(wall_list.equals("wall003")){
     mWall = R.drawable.wall003;

     }else if(wall_list.equals("wall001")){
     mWall = R.drawable.wall001;
     
     …その他変更処理いろいろ
     
     onCreate(getSurfaceHolder());
     onSurfaceCreated(getSurfaceHolder());
     
    }



    まー、drawのメソッドがないならもう一回surfaceをCreateすればええんちゃう?
    とやってみたら、ダメでした。そらそーだ、これだと初回読み込みとかにも
    エラー出るし、この状態でパーティクルの再描画もしたら変更した瞬間に
    処理が追いつかなくてオーバーフローでした。
    で、↑を↓に変えたらOKでした。


    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    {
     String wall_list = sharedPreferences.getString("list_key","wall001"); //preference.xmlに設定したキーと初期値
     if(wall_list.equals("wall002")){ //処理いろいろ。ここではリストから選択して壁紙変更
     mWall = R.drawable.wall002;
     }else if(wall_list.equals("wall003")){
     mWall = R.drawable.wall003;
     }else if(wall_list.equals("wall001")){
     mWall = R.drawable.wall001;
     }
     …その他変更処理いろいろ
    }
    if(gl != null){
     onSurfaceDestroyed(getSurfaceHolder());
     onCreate(getSurfaceHolder());
     onSurfaceCreated(getSurfaceHolder());
     onVisibilityChanged(false);
     }
    }




    やったこと
    ・最後のif文で、glがnullじゃないときのみ再描画処理を行う(初回起動対策)
    ここでいうglはThreadを継承したOpenGLの開始処理とかを行うクラス。
    ていうか本に載ってるママの変数。

    ・if文で判別したら、再描画処理するんだけど、まずは
     onSurfaceDestroyed、で破壊→そののちにonCreate。単なる
    draw処理じゃなくて一度破棄しないとダメみたい。

    ・最後にonVisibilityChangedでポーズ状態にする。
    これをしないと変更した瞬間に、変更画面のままパーティクルが動きまくって
    処理エラーになります。(何を隠そうここが一番ハマった)


    同じ本を使って作っている人の参考になれば幸いです。
    そして多分もっといい方法があると思うので教えてくれる素敵な
    人たちを募集中です。




    カテゴリ
    検索フォーム
    メールフォーム

    名前:
    メール:
    件名:
    本文:

    お世話になっている書籍達




















    リンク



    最新記事
    月別アーカイブ
    最新コメント
    プロフィール

    yukinori110

    Author:yukinori110
    Androidってなに?Javaってなに?というレベルから勉強してます。