2013年12月15日日曜日

[Glaeja] ♫あなたの色に染められ

久しぶりのチュートリアルエントリです。

こないだ、過去に書いたチュートリアルをざっと眺めてみたんですが、その多くはv2以前に書かれたもので、現在ではもっと便利なレイヤーやエスケープキャラクタを使って作れるものがいくつもありました。

そこで、【逆引きGlaeja】とまではいきませんが、最新(ver.4.4.0)の機能を使った、シチュエーション別のチュートリアルを作ってみたいと思います。

まず、本エントリでのシチュエーションは『色を変化させる』にしてみました。



さて、『色を変化させる』といっても、その変化させたい対象は様々です。また、変化のさせ方も、「別の色に変える」場合と、「色のついている場所を変える」場合があります。

そこで、以下の3つのシチュエーションについてチュートリアルを作ってみます。
  1. 「テキスト」の色を変える
  2. 「テキスト」以外の色を変える
  3.  色のついている場所を変える

1.「テキスト」の色を変える


色んな所で良く耳にする質問に、「バッテリー残量で数字の色を変えたい」というものがあります。「0~20%なら赤、21~40%ならオレンジ、41~60%なら黄、61~100%なら緑で残量%の数字を表示する」って感じですかね。

こうした
  • テキスト(もしくはその一部)」を
  • 決められた数の色のうちから
  • システム情報に応じてどの色にするかを決定する
という場合、いくつかやり方が考えられるのですが、最も簡単なのは「リッチテキスト」レイヤーを使う方法です。

「リッチテキスト」レイヤーには、『文字列群の各文字列が空文字ならその文字列は表示されない』という、いわば当たり前の機能があります。これを利用して、以下のような構成の文字列群を作ってやるわけです。
  1. 色は赤で、バッテリー残量が0~20%なら#P#を、そうでないなら空文字を表示
  2. 色はオレンジで、バッテリー残量が21~40%なら#P#を、そうでないなら空文字を表示
  3. 色は黄で、バッテリー残量が41~60%なら#P#を、そうでないなら空文字を表示
  4. 色は緑で、バッテリー残量が61~100%なら#P#を、そうでないなら空文字を表示
こうすれば、バッテリー残量#P#の値に応じて上記4つのどれか1つしか表示されないため、目的通りの描画結果になるわけです。


実際の「リッチテキスト」レイヤーの文字列群設定は、こんな感じですかね。

上記例では、トータルとして文字列全体の色が変化していますが、「リッチテキスト」レイヤーですので、文字列群の他の部分に文字列を追加すれば、色の変化しないテキストを作ることも可能です(例えば、『バッテリー:#P#%』という文字列の#P#だけ色を変化させる、とか)。

このやり方は、『必要な部分に色をつける』のではなく、『とりあえず全色描いてから不要な部分を削除する』というものに近い発想方法です。このような考え方は『Glaeja』のウィジェット作成では頻出しますので、是非覚えておいてください。


2.「テキスト」以外の色を変える


例えば、バッテリー残量を「バー」や「サークル」で表現していて、その色を「0~20%なら赤、21~40%ならオレンジ、41~60%なら黄、61~100%なら緑」で表示する、というような場合ですね。

これもいくつかやり方があるのですが、一番簡単なのは「色と透過度」レイヤーを使う方法です。

「色と透過度」レイヤーは、対象となるレイヤーを構成する全ピクセルの色(RGB)と透過度(A)を操作する効果レイヤーです。
ARGBの4つに対して「0~255」の値を設定することで、強制的にその値に再設定します。またその範囲外の数値(例えば「-1」)を設定した場合には、元の値を保持します。
つまり、透過度(A)に「-1」を設定した場合には、対象レイヤーの「色がついてる(=無色透明でない)」部分だけ、色(RGB)が変更される、わけです。

「0~20%なら赤、21~40%ならオレンジ、41~60%なら黄、61~100%なら緑」場合ですと、
  •  0~20%なら赤(#FFFF0000
  • 21~40%ならオレンジ(#FFFF8A00
  • 41~60%なら黄(#FFFFFF00
  • 61~100%なら緑(#FF00FF00
ですので、これを「色と透過度」レイヤーのパラメータに直すと、以下のようになります。
  • R」は、0~20%なら「#FF」、21~40%なら「#FF」、41~60%なら「#FF」、61~100%なら「#00
  • G」は、0~20%なら「#00」、21~40%なら「#8A」、41~60%なら「#FF」、61~100%なら「#FF
  • B」は、どの#P#でもすべて「#00
  • A」は、どの#P#でもすべて「-1
エスケープキャラクタを使って、実際の「色と透過度」レイヤー設定画面に記述すると、下図のようになります。


これを[レベルの色:#FF999999、サークルの背景色:#00000000]に設定した、バッテリー残量を表すサークルに適用すれば良いのです(下図)。


このとき注意する点として、対象となる「サークル」レイヤーは[サークルの背景色]の透過度(A)が「#00」でなければなりません。そうでないと背景部分にも「色と透過度」レイヤーが適用されてしまい、サークル全体が同じ色に塗りつぶされてしまいます。
ですので、背景色として別の色をつけたい場合には、背景色のためだけに別のサークルを下に置く必要があります。


3. 色のついている場所を変える


ちょっとざっくりとまとめてしまいましたが、これは「変える対象がテキスト内かどうか」「変える箇所が1箇所かどうか」でさらに細分化されます。

例えば、「『0・10・20・30・40・50・60・70・80・90・100』という白文字のテキストにおいてバッテリー残量に該当する部分のみ黒文字となっている」ようなスキンを考えてみます。以下の図のような感じですかね。


このように、
  • テキスト内で
  • 1箇所だけ色を変えて
  • 他の部分は同じ色
である場合には、「マッチテキスト」を使うのが簡単です。

このスキンの場合には、
  • 元の文字列
    • 表示文字列:0・10・20・30・40・50・60・70・80・90・100
    • 文字の色:#FFFFFFFF
  • 対象の文字列
    • 置換して表示する:チェックあり
    • 置換文字列:#P#
    • 探索文字列:#P#@p@0,10,20,30,40,50,60,70,80,90,100,101@0/-1/\g@@p@,0,10,20,30,40,50,60,70,80,90,100@0/-1/\m@
    • 文字の色:#FF000000
とすれば良いでしょう。

では、上記スキンに「現在のバッテリー残量より大きい部分は灰色で表示する」という条件を追加してみましょう。以下のような感じですかね。


この場合、該当する部分以外の色が複数になっていますので「マッチテキスト」は利用できません。
こうした、
  • テキスト内で
  • 複数箇所の色を変える
場合には、「リッチテキスト」を使います。

このスキンの場合ですと、
  1. 現在のバッテリー残量より前の文字列を白で表示
  2. 現在のバッテリー残量を黒で表示
  3. 現在のバッテリー残量より多い部分を灰色で表示
という文字列群を組み立てれば良いでしょう。


実際の記述としては、こんな感じになります。


これら2つは「同一のテキスト」内で色をつける場所を変えたものでした。では、「マルチラインテキスト」や複数の「テキスト」が垂直に並んだようなものにおいて、色をつける場所を変えるにはどうすれば良いのでしょうか。

例えば、下図のような、バッテリー残量スキンが垂直に並んだもの、というのを考えてみます。


これは、色を考慮しないのであれば、以下のような「マルチラインテキスト」で実現できます。


この「マルチラインテキスト」の現在のバッテリー残量に該当する部分の色を変えるには、「バー」レイヤーと「転送モード」レイヤーを使います。

まず、現在のバッテリー残量に該当する行の部分が黒、それ以外が白、となるような「バー」レイヤーを作ります。
アンカーポイントは適当ですが、「マルチラインテキスト」と横並びにしておくと動作確認がし易いでしょう。


黒いレベル部分の位置が、どのバッテリー残量でも正しくなるように、サイズやレベル開始/終了を設定し、「バー」が「マルチラインテキスト」全体を覆い隠すようにアンカーポイントを設定します。


そして、この「バー」レイヤーに「転送モード」レイヤーの効果をかけてやります。
[転送モード]は
  • 作業領域への転送:対象の上に合成
  • 描画済領域への転送:このレイヤーを対象の形に切り抜く
とします。
つまり、「現在のバッテリー残量に相当する部分が黒い白帯を、バッテリー残量のマルチラインテキストで切り抜く」ことになるわけです。

仕上がりとレイヤーリストは下図のようになります。


この、『とりあえず単色で全部描いてから、必要な部分に「転送モード」で色をつける』というテクニックは、覚えておくと表現の幅が広がるテクニックです。



とりあえず以上まで。もうちょっと思いついたら追加するかも知れません。

11 件のコメント:

  1. 昔の記事に失礼します。

    電池が20%以下、21%以上40%以下、41%以上61%以下、61%以上でそれぞれ表示する画像を変えたい時はどうすればよいのですか?

    返信削除
    返信
    1. 「イメージ」か「スプライト」レイヤーで、
      電池残量に応じて表示する画像ファイル名が変化するように
      [ファイル…]→[パターン文字列で指定…]に@@を書けばよろしいかと。

      削除
    2. なるほど、わからん。

      素早い対応、ありがとうございます。

      削除
  2. また失礼します。
    ちょっと頑張ってみたいと思うので、少し詳しく説明がいただけたらと思います。

    充電率で色ではなく画像が切り替わるようにする場合、どのような文字列になるのでしょうか。
    大体、とかこれを参考に、とかでもいいので教えていただきたいです。

    返信削除
    返信
    1. http://bananawani-mc.blogspot.jp/2011/08/android-case-of-cottingley.html

      ここの「・ドロイド君のバッテリー残量ゲージを作ってみよう」とかですかね

      削除
    2. ありがとうございます!

      これを参考に……あとはそう、場所を固定にするだけ……頑張ります、できるだけ。笑

      削除
    3. そうだ、「その後ろ一文字目から二文字」というのは、「012」だったら0から数えて二文字の、「0と1」ということでいいのですか?

      削除
    4. 全然違います。
      「その(バッテリー残量として出力された3桁の数値の)後ろ一文字目から(右に数えて)二文字」です。
      「012」なら「2と1」ですね。

      以下熟読
      http://bananawani-mc.blogspot.jp/2011/10/android.html

      削除
  3. えと、一応読んでみました。

    ドロイド君を参考にするとなりますと、開始位置と終了位置を同じ場所にすれば画像は固定できる、であってますでしょうか。

    また、使いたいファイルにはそれぞれ残量でb9、b8、b6、b4、b2と名前をつけてあるのですが、あれをそのまま使うと充電がないのに多い状態の画像になったりしてしまいませんか?
    その辺がよくわかりませんでした。

    素人考えなので面倒かと思いますが、気が向いたらでいいのでお返事をいただけたらと思います。

    返信削除
    返信
    1. ええ、面倒ですw

      「|...|」を使わなければ端末を壊すことは決してありませんので、

      ちょっと変えては実際に試す、

      を繰り返して理解を深めていけばイイのではないでしょうか。

      削除
  4. うう、すいません……

    色々試して頑張ってみたいと思います。
    ありがとうございました。

    返信削除