2012年3月31日土曜日

【Java】オブジェクトの比較

前回は条件文と演算子について書きましたが、その中で値の比較を行っていました。
if (num == 0) { } // 変数宣言は省略
みたいなのです。
numと0が等しいかどうかを比較しています。

それでは文字列を扱うString型の比較はどうでしょうか?
String zero = "0";
if (zero == 0) { } // TRUEを返す
これはTRUEとなります。
では次のはどうでしょう?
String zero = "0";
String zeroNew = new String("0");
if (zero == zeroNew) { } // FALSEを返す
これはFALSEとなります。
参照型の場合はプリミティブ型の場合と異なり、
値そのものでなくオブジェクトの比較が行われます。
この場合、newされたzeroNewが指す"0"を格納したアドレスは
zeroのものとは違うアドレス(それこそ新しいアドレス)のため、FALSEとなります。

以前説明に使用したジョブクラスを使用して説明してみます。
シーフ siroco = new シーフ(); // シーフクラスのsirocoインスタンスを生成
シーフ kururu = new シーフ(); // シーフクラスのkururuインスタンスを生成

if (siroco == kururu ) { } // FALSEを返す
この方がわかりやすいんじゃないでしょうか?
同じシーフクラスのインスタンスでも、sirocoとkururuは別人ですもんね。

それではオブジェクトが指している"値"を比較するにはどうしたらいいでしょうか?
それはObjectクラスのメソッド、equalsを使用します。
String zero = "0";
String zeroNew = new String("0");
if (zero.equals(zeroNew)) { } // TRUEを返す
この例ではString型のzeroインスタンスのequalsメソッドを使用して、
 同じくString型のzeroNewインスタンスとの比較を行っています。
(参照型のクラスはすべてObjectクラスを継承しているため、equalsを使う事が出来る)
equalsなら別インスタンスでも値の比較ができ、求めている結果が得られます。

文字列の比較は結構やると思いますので、
くれぐれも"=="で比較しないように~

今回は以上です。
次回は繰り返し処理について書いていきます。

2012年3月24日土曜日

【Java】条件文と演算子

プログラムを組んでいる際、条件を与えて
その条件ごとで処理を変えたいことがあります。

例えば、
右の宝箱を開けると「ブレイブブレイド」がもらえる。
左の宝箱を開けると「チキンナイフ」がもらえる。
みたいな時です。
(やっぱりFF5。因みにsirocoはチキンナイフ派)

これをJavaで書くと次のような感じ。
if (右の宝箱を選択) {
 // ブレイブブレイドを入手
} else {
 // チキンナイフを入手
}
簡単な英語が分かれば理解できると思いますが、
if を使用して条件文を表すことができます。
if のあとの括弧内に条件をいれ、それが真の時に { } 内の処理を実行します。
else はif の条件を満たさない場合を意味し、else以降の { } 内の処理を実行します。

では次の条件をif 文で書いてみます。
『変数num が0ならば、変数str に"ぜろ"を代入し、num が1ならば、str に"いち"を代入し、それ以外なら、str に"それ以外"を代入』
int num = 0;
String str;

if (num == 0) {
 str = "ぜろ";
} else if (num == 1) {
 str = "いち";
} else {
 str = "それ以外";
}
else のあとに if を続けることで、条件を続けて書くことができます。
"=="は、その左の値と右の値が一致するという意味です。
(オブジェクトの場合は、左右のインスタンスが一致)

"=="など値の比較を行うものを、比較演算子と言います。
比較演算子には次の種類があります。

<小なり
<=小なりイコール
==イコール
>=大なりイコール
>大なり

『変数num が10より大きくて、且つ20より小さい場合は変数str に"あたり"を代入』
これをif 文で書くと、、、
int num = 12;
String str;

if (num > 10) {
 if (num < 20) {
  str = "あたり";
 }
}
条件を加えてみましょう。
『それ以外の場合は、strに"はずれ"を代入』
int num = 12;
String str;

if (num > 10) {
 if (num < 20) {
  str = "あたり";
 } else {
  str = "はずれ";
 }
} else {
 str = "はずれ";
}

なんだか見にくいですね。
おまけに"はずれ"を代入するところが重複しています。
これは次のように書きかえれます。
int num = 12;
String str;

if (10 < num && num < 20) {
 str = "あたり";
} else {
 str = "はずれ";
}
すっきりしました。
ここで出てくる"&&"はANDを意味し、短絡演算子と言います。
短絡演算子は次の種類があります。

&&論理積(AND)
||論理和(OR)

これでたいていの条件文は書けるんではないでしょうか。

ここで補足。
if 文の括弧の中に入る条件はboolean型です。
(真偽値、TRUEとかFALSEってやつ。ここででてきた)

つまり次のような書き方もできます。
int num = 12;
String str;

// boolean型の変数isHitに条件式を代入
boolean isHit = 10 < num && num < 20;

if (isHit) {
 str = "あたり";
} else {
 str = "はずれ";
}

まあ、通常はこんな書き方はしないでしょうが、
メソッドの戻り値にbooleanを使用する場合なんかはありますね。
演算子の説明をしてきたので、その他の良く使う演算子も紹介します。
まずは算術演算子。

+加算(足し算)
-減算(引き算)
*乗算(掛け算)
/除算(割り算)
%余算(余り)
int num1 = 10 / 2;       // 5を代入(10÷2)
int num2 = 2 + 8 / 2;    // 6を代入((8÷2)+2)
int num3 = (2 + 8) / 2;  // 5を代入((8+2)÷2)
演算順序は算数と同じですね。
(わからない人は小学校の算数を見直しましょう(笑))

あとは論理演算子。

&論理積(AND) 
|論理和(OR) 
^排他的論理和(XOR)
!否定(NOT)

これはあまり使わないかもしれませんが、"!"は良く使うので覚えておいたほうがいいです。
int num = 12;
String str;

// boolean型の変数isHitに条件式を代入
boolean isHit = 10 < num && num < 20;

// isHitでない、という意味になる
// つまり10以下、もしくは20以上の場合に"あたり"を代入することとなる
if (! isHit) {
 str = "あたり";
} else {
 str = "はずれ";
}


今回は以上です。
次回はオブジェクトの比較について書いてみようかな~
(最近blogばっかり書いてアプリ作りしてない気がするw)

【Java】コンストラクタと継承 with FF5

前回、FF5のジョブをクラスとしてインスタンス化することを書きましたが、
今回はその続きです。

おさらいがてらジョブをクラスとして宣言していきます。
public class ナイト {

 public void たたかう() {
  // 装備している武器で攻撃する
 }
 
 public void ぼうぎょ() {
  // 身を守り、ダメージを軽減する
 }
 
 public void 両手持ち() {
  // 武器を両手で持ち、攻撃力を倍増させる
 }
  ・
  ・
  ・
}
public class シーフ {

 public void たたかう() {
  // 装備している武器で攻撃する
 }
 
 public void ぼうぎょ() {
  // 身を守り、ダメージを軽減する
 }
 
 public void ぬすむ() {
  // モンスターの持つ宝を盗む。失敗することもある
 }
  ・
  ・
  ・
}
public class 黒魔道士 {

 public void たたかう() {
  // 装備している武器で攻撃する
 }
 
 public void ぼうぎょ() {
  // 身を守り、ダメージを軽減する
 }
 
 public void 黒魔法() {
  // 黒魔法を使用する
 }
  ・
  ・
  ・
}
各ジョブを見てもらうと気付くと思いますが、
「たたかう」や「ぼうぎょ」などのメソッドはどのジョブでも使用可能なメソッドで、
その内容も一致しています。
これを大量にあるすべてのジョブに実装していくのは面倒ですね。
それどころか、ゲームの仕様が変わって「たたかう」が「こうげき」に変わったらどうでしょう?
すべてのジョブのすべてのメソッドを修正しないといけません。

そこでJavaには継承という機能が用意されています。
各ジョブの共通部分をまとめた"ジョブ"というクラスを作ってみます。

public class ジョブ {

 public int lv; // キャラクターのレベル
 public int hp; // キャラクターのヒットポイント
 public int mp; // キャラクターのマジックポイント

 public ジョブ() {
  // 初期値としてlv=1,hp=50,mp=5を設定し、引数付きコンストラクタを実行
  this(1, 50, 5);
 }

 public ジョブ(int lv, int hp, int mp) {
  this.lv = lv;
  this.hp = hp;
  this.mp = mp;
 }

 public void たたかう() {
  // 装備している武器で攻撃する
 }
 
 public void ぼうぎょ() {
  // 身を守り、ダメージを軽減する
 }
 
 public void チェンジ() {
  // 隊列を変更する
 }

 public void アイテム() {
  // アイテムを使用する
 }
}
見慣れない部分があると思います。
まず3~5行目の変数はメンバ変数(クラス変数)といい、
クラス内のどのメソッド、コンストラクタでも共通で使用できる変数です。
この例ではRPGに必須のレベルやHPをメンバ変数にしてみました。

次に7行目と12行目から始まるメソッド。これがコンストラクタです。
コンストラクタはクラスをインスタンス化(newする)際に呼ばれるメソッドで、
フィールドの初期化などを主に行います。

コンストラクタのメソッド名はクラス名とし、戻り値はなし(型も記述しない)です。

[修飾子] クラス名 (引数,・・・) { }

コンストラクタは複数設定可能で、7行目は引数なしのコンストラクタ。
12行目は引数付きのコンストラクタです。
実際にインスタンス化すると次のような感じです。

public class TestFF5 {

 public static void main (String[] args){
  
  // LV.1、HP50、MP5のジョブクラスのインスタンスsirocoが生成されます
  ジョブ siroco = new ジョブ();
  
  // LV.20、HP500、MP200のジョブクラスのインスタンスkururuが生成されます
  ジョブ kururu = new ジョブ(20, 500, 200);
 }
}
イメージが湧いたでしょうか??
因みにジョブクラスの引数なしコンストラクタのところで
"this(1, 50, 5)"とありますが、thisというのは自らのことで、
ここでは引数付きのコンストラクタを示します。
つまり"ジョブ(1, 50, 5)"と同意です。

また、引数付きのコンストラクタの中で"this.lv"などここでもthisを使用していますが、
これはコンストラクタの引数のlvと区別するために付けています。
(クラスのフィールドは本来はすべて"this."をつけれるが、不要な時は省略できます)


さて、ここからが本題。
各ジョブの共通部分をまとめたジョブクラスが出来たので、
それを継承して各クラスを作ってみましょう。
public class ナイト extends ジョブ {

 public ナイト() {
  super.hp = super.hp * 1.2;
  super.mp = super.mp * 0.6;
 }

 public void 両手持ち() {
  // 武器を両手で持ち、攻撃力を倍増させる
 }
  ・
  ・
  ・
}
public class シーフ extends ジョブ {

 public void ぬすむ() {
  // モンスターの持つ宝を盗む。失敗することもある
 }
  ・
  ・
  ・
}
public class 黒魔道士 extends ジョブ {

 public void 黒魔法() {
  // 黒魔法を使用する
 }
  ・
  ・
  ・
}
public class TestFF5 {

 public static void main (String[] args){
  
  // シーフのインスタンスsirocoが生成されます。
  // このとき、スーパークラスであるジョブクラスの引数なしコンストラクタが実行され、
  // 各メンバ変数ははLV.1、HP50、MP5となる
  シーフ siroco = new シーフ();

  // スーパークラスであるジョブクラスのたたかうメソッドが実行される
  siroco.たたかう();
  
  // 黒魔道士クラスのインスタンスkururuが生成されます。
  // このとき、スーパークラスであるジョブクラスの引数付きコンストラクタが実行され、
  // 各メンバ変数はLV.20、HP500、MP200となる
  黒魔道士 kururu = new 黒魔道士(20, 500, 200);

  // 黒魔道士クラスの黒魔法メソッドが実行される
  kururu.黒魔法();

  // ナイトクラスのインスタンスrenaが生成されます。
  // このとき、スーパークラスであるジョブクラスの引数なしコンストラクタが
  // 実行され、メンバ変数はLV.1、HP50、MP5となります。
  // そのあとナイトクラスのコンストラクタが実行され、
  // ジョブクラスのhpを1.2倍、mpを0.6倍にして代入しています。
  // つまりrenaの状態はLV.1、HP60、MP6となります
  ナイト rena = new ナイト();
 }
}
クラスを継承するには、クラス宣言の際に"extends 継承するクラス名"で行います。
継承したクラス(子クラス)は継承元のクラス(親クラス、スーパークラス)の
フィールドを使用できます。

これでどのジョブからでも「たたかう」や「ぼうぎょ」を使う事が出来ます。
また、共通部分の変更が発生しても、スーパークラスであるジョブクラスを
修正するだけで、すべてのクラスで修正後のメソッドを使用できます。

上の例でナイトクラスにだけコンストラクタを設定しています。
他のジョブについては記述していませんが、この場合は引数なしの
デフォルトコンストラクタが暗黙に宣言されています。


因みに、ナイトクラスのコンストラクタ内でスーパークラスのメンバ変数に
直接あたいを代入しているが、これはあまりよろしくありません。
メンバ変数をprivate宣言し、アクセッサメソッド(ゲッター・フッター)を使うほうが良いです。
今回は説明前なので、あえて直接代入とさせています。(そのほうがわかりやすいと思って)


インスタンス化の際のコンストラクタの実行順としては、
まずスーパークラスのコンストラクタが実行され、
そのあと子クラスのコンストラクタが実行されます。


長々と書いてきましたが、継承について少しは感じがつかめたでしょうか?
細かいことを書けば、大量の説明が必要になるので、書きませんが、
詳しく知りたくなった人は古本屋さんとかでJavaの本を手にとって見てはいかがでしょう??

次回は条件文について書こうと思います。
(ここは流石にFF5は無理かな~)

Javaを始めるなら。。。

sirocoがJavaを始めた時に参考にした本です。
他にもJavaの本は持ってるけど、結城さんのは読みやすいと思います。


2012年3月23日金曜日

【Java】クラスとインスタンス with FF5

クラスとは同様の状態・振る舞いをもつオブジェクトの共通部分を集めて
1つの型を構成することです。
ここでいう状態はクラス変数(メンバ変数)などを示し、
振る舞いはメソッドを示します。

固く書いてもわかりずらいので、最近sirocoがやっているゲーム「FF5」を
例に挙げて説明してみます(笑)

FF5にはジョブというシステムがあります。
ナイト・シーフ・白魔道士などなど。
これら各ジョブをクラスに表してみます。
public class シーフ {

}
クラスの宣言は以下のようになります。

[修飾子] class クラス名 { }

上の例ではpublic(どこからでも使用できる)なシーフというクラスを宣言しています。
クラスの持つ状態や振る舞いは "{" と "}" の間にコーディングします。

ジョブには特有のアビリティがありますので、
それをメソッドとしてあらわしてみます。
public class シーフ {

 public void かくしつうろ() {
  // ダンジョンなどの隠し通路が見えるようになる
 }
 
 public void とんずら() {
  // 戦闘から逃げる。逃げられないモンスターもいる
 }
 
 public void ダッシュ() {
  // キャンセルボタンを押しながら移動すると、2倍の速度で動ける
 }
 
 public void ぬすむ() {
  // モンスターの持つ宝を盗む。失敗することもある
 }
  ・
  ・
  ・
}
メソッドの宣言は以下のようになります。

[修飾子] [戻り値の型] メソッド名 { }
メソッドの内容については、また別の機会に。

さて、上で宣言したシーフクラスは1つのオブジェクトですが、
オブジェクトそのものでは使用できず、
インスタンス化をして始めて使用可能となります。
(staticなフィールドは別ですが)

インスタンス化の例を挙げてみます。
public class TestFF5 {

 public static void main (String[] args){
  
  // シーフクラスのインスタンスsirocoを生成
  シーフ siroco = new シーフ();
  
  // とんずらメソッドの使用
  siroco.とんずら();

  // シーフクラスのインスタンスkururuを生成
  シーフ kururu = new シーフ();

  // ぬすむメソッドの使用
  kururu.ぬすむ();
 }
}
てな感じです。
変数やメソッドをクラスとして宣言し、インスタンス化することで、
sirocoとkururuのそれぞれで、オブジェクトのフィールド(変数やメソッド)を
使用できるようになります。


クラスとインスタンスについては、こんなところで。
次回以降でもう少し掘り下げて説明していきます。

。。。勿論、FF5を使ってね(笑)

2012年3月22日木曜日

【Java】変数の宣言と値の代入

変数はプログラム中で使用する変動する値のことで、
宣言をすることで使用可能となります。
Javaの変数の宣言は次の形で行います。

[型] 変数名;

int i;     // int型のiという変数を宣言
double d;  // double型のdという変数を宣言
Object o;  // Object型のoという変数を宣言
String s;  // String型のsという変数を宣言

変数の宣言はプリミティブ型でも参照型でも同様となります。
実際には[型]の前に修飾子を付けることができますが、
複雑になるので別の機会に。

続いて値の代入を見ていきます。
代入の方法はプリミティブ型と参照型で異なります。
(前回説明したところです。⇒プリミティブ型と参照型

まずはプリミティブ型。
値を直接代入します。
int i = 123;     // int型の変数iに123を代入
double d = 1.23;  // double型の変数dに1.23を代入

次に参照型。
インスタンスを生成して代入します。
(インスタンスについては次回詳細を説明します。)
もっとも基本的なインスタンスの生成は new クラス名() で行います。
Object o = new Object(); // Date型のdateという変数を宣言

なお、String型のみが参照型の中でも特別扱いされています。
Stringは、不変の(内容が変更されない)文字列を扱うクラスですが、
あまりに良く使うクラスの為、"(ダブルコーテーション)で括った文字列を直接代入できます。
// String型の変数s1に"abc"という文字列を代入
String s1 = "abc";

// これはs1とは別のオブジェクトとなる(参照先が異なる)
String s2 = new String("abc");

// Stringは不変なのでnewでインスタンス化するのは無意味
String s3 = new String();

こんなとこかな。

【こんにちは赤ちゃん】ver2.1.0 リリース



こんにちは赤ちゃん
⇒マーケットはこちら


更新内容
今まではウィジェットをクリックした場合のみ遷移させていた赤ちゃんの様子画面へ、
設定画面からも遷移出来るように変更しました。


お知らせ
前回のバージョンアップから、「こんにちは赤ちゃん」使い方ページも更新しています。
こちらからどうぞ。


最近、ウィジェットが起動しないというコメントが多くなってきたので、
思い切って設定画面から遷移させてみました。
上記不具合の暫定対策ですね。

本当はウィジェットが設定できないHOMEアプリとかにしてるのが
原因だと思うんだよな~
現に同一端末で普通に使えている人がたくさんいるんだし。。。

2012年3月16日金曜日

【Java】プリミティブ型と参照型

Javaの型には、プリミティブ型と参照型がある。
(特殊な空型というのもあるが、ここでは触れない)

プリミティブ型

整数値などの"値"を扱う基本的な型で次の8つのことを指す。

範囲
byte符号付き整数-128 ~ 127
short符号付き整数 -32768 ~ 32767
int符号付き整数 -2147483648 ~ 2147483647
long符号付き整数 -9223372036854775808 ~ 9223372036854775807
float浮動小数4バイト浮動小数点数
double浮動小数 8バイト浮動小数点数
charUnicode文字'¥u0000' ~ '¥uffff'
boolean真偽値TRUE , FALSE

これに加えて"型がない"ことを意味するvoidという方も基本的な型です。

void型なし

int i = 123;
double d = 1.23;

参照型

上記で説明したプリミティブ型以外はすべて参照型です。
参照型にはクラス、インターフェース、配列などが含まれます。
(文字列を扱うStringもクラスなので参照型)
すべての参照型はObjectクラスを継承しています。

参照型と言われるのは、保持する値が"値そのもの"ではなく、
メモリー上に格納されたオブジェクトの先頭アドレスに当たるものを保持しているからです。
(プリミティブ型は"値そのもの"を保持している)

String s1 = "笑い男";
String s2 = "123";

※詳細はクラス、インターフェース、配列の説明の際に。。。

2012年3月10日土曜日

【こんにちは赤ちゃん】ver2.0.0 リリース



こんにちは赤ちゃん
⇒マーケットはこちら


更新内容
UIを変更しています。

まず、赤ちゃんの性別を選択できるようにしました。
これにより、ウィジェットの赤ちゃんの名前+"くん"の表示もできるようになります。

ウィジェットのテーマの設定方法をテーマとカラーを分割して設定する方法へ変更しました。
これにより、今まで縦の長いリストで見づらかったのが解消しています(と願っています)。

ウィジェットのカラーにpurpleを追加しました。
他のカラー同様にプレーン、水玉、ボーダーそれぞれ選択できます。
(少し暗い色合いになってしまった。。。)

お知らせ
今回のバージョンアップに伴い、「こんにちは赤ちゃん」使い方ページも更新しています。
こちらからどうぞ。


久々のアップデートとなります。
UIを変更していることもあり、バージョンは一気に 2.x.x にしました。
これからもそれなりにアプデしていきたいな~

【こんにちは赤ちゃん】使い方について(ver 2.0.0 以降)


「こんにちは赤ちゃん」は妊娠週数をウィジェットで表示するアプリケーションです。
通常のランチャーから起動するアプリとは設定方法が異なりますので、使い方を説明します。

※バージョンが ver 1.4.1 以下の場合はこちらをご確認ください。

1. アプリをダウンロードしたら、一覧画面から「こんにちは赤ちゃん」を選択し起動します。


2. 起動したら設定画面が表示されますので、"赤ちゃんの情報設定"と"ウィジェット設定"の項目を設定してください。


赤ちゃんの情報設定
赤ちゃんの名前ウィジェットに表示する赤ちゃんの名前です。
未入力の場合、"赤ちゃん"が設定されます。
性別ウィジェットに表示する赤ちゃんの敬称です。
選択した性別に合わせて"くん"、"ちゃん"を表示します。
出産予定日入力された日付より妊娠週数を算出し、ウィジェットに表示します。
未入力の場合、入力日が設定されます。
ウィジェット設定
テーマウィジェットのテーマです。
選択したテーマのウィジェットを表示します。
"Random"を選択するとランダムにテーマが選択されます。
テーマカラーウィジェットテーマのカラーです。
選択したカラーのウィジェットを表示します。
その他
赤ちゃんの様子妊娠月齢ごとの赤ちゃんとお母さんの様子を表示します。
About「こんにちは赤ちゃん」についての説明画面を表示します。
Help「こんにちは赤ちゃん」の使い方画面(当画面)を表示します。



3. 設定が完了したら”戻る”ボタンでアプリを終了します。

4. ホーム画面を長押しし、表示されたリストから”ウィジェット”を選択します。

※Android 4.0 以降の方は、アプリ画面を右にスワイプし、”ウィジェット”タブから「こんにちは赤ちゃん」を選択します。
「こんにちは赤ちゃん」のウィジェットを長押しでホーム画面に張り付けることができます。

5. ウィジェット一覧の中から「こんにちは赤ちゃん」を選択します。


6. ウィジェットが表示されました。


7. ウィジェットをタップ(クリック)すると、現在の月齢の情報が表示されます。


8. ”back”ボタンや”next”ボタンを押す事で前後の月齢の情報を表示する事も出来ます。


以上です。
不明点等ありましたら、遠慮せずにご質問下さい。


=== 追伸 ===
各バージョン情報を載せておきます。
- ver 2.1.2 バグ修正
- ver 2.1.1 桜テーマの追加
- ver 2.1.0 設定画面から赤ちゃんの様子を確認可能へ
- ver 2.0.0 UIの変更など
============

2012年3月3日土曜日

2027のアプリ作ろうかな。。。

2027のBM継続率を予測するアプリを作ろうと思う。

潜航モード中の爆発の大中小と、
チェリー後の子役成立(入賞)のカウントを行う事で算出。
すでに解析である程度の数値は出てるから、それを参考に。

画面構成は、、、
メイン画面 潜航モードのカウント、チェリー後のカウント、予測結果表示への遷移
潜航モードのカウント画面 子役ごとの爆発の大きさをカウント
チェリー後のカウント画面 潜航モード(画面は通常)の残りゲーム数の表示
子役ごとのカウント、チェリー追加成立時のゲーム数の加算
予測結果表示画面 それぞれのカウント結果より溜まっているpointを算出し、継続率を表示

こんなとこかな。
せっかくだから2027の素材使いたいのでJPSに問合わせ中。
(全然返事こないや)


因みに、2027の全国設置台数は100件以下。。。(爆)

【Forest君用】TextViewを動的に表示させる方法 その2

前回のTextViewのテキスト設定の説明の最後に
「Hello World!」アプリの画面と異なると言いましたが、
違いは画面レイアウトです。

前回作成した画面はTextViewをアクティビティに設定しています。
つまり、単一のTextView要素を表示させています。

「Hello World!」アプリの画面はLinearLayoutをアクティビティに設定しています。
この場合、LinearLayoutの要素として複数のViewを表示させることが可能です。

実際のアプリの画面としては後者が有効で、
単一のView要素をアクティビティに設定することは、まずないでしょう。

じゃあ前回やったことは無駄なの?って思うかもしれませんが、
そんなことはありません。
今回はxmlファイルで定義したLinearLayoutのTextView要素にJavaソース内で
テキストを設定します。
そこで前回の内容が生きてくるんです!

ではでは。
まずはxmlで定義するTextViewをJavaソースで特定できるように
IDを設定します。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
    android:id="@+id/text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

</LinearLayout>

「Hello World!」アプリのものに8行目を追加しただけです。
TextViewにtextというIDを関連付けしています。

次にJavaソース。
package jp.gr.java_conf.siroco.helloandroid;

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

public class HelloAndroidActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // IDからTextViewインスタンスを取得
        TextView textView = (TextView) findViewById(R.id.text);

        // 表示するテキストの設定
        textView.setText("STAND ALONE COMPLEX");

        // ActivityにViewを設定
        setContentView(textView);
    }
}

前回作ったものと異なるのは14行目です。
findViewByIdメソッドを使用してViewを定義しています。
findViewByIdメソッドはその名の通り、IDからViewを検索します。
引数で与えた「R.id.text」が、先ほどxmlファイルで設定したID「text」を指します。

IDから取得したTextViewインスタンスに対してテキスト設定~Activityへのセットを行います。
(インスタンスの生成方法以外は同様ですね)


今回は以上です。
ここまでくれば、画面表示の基本の設定はマスタです。
(基本中の基本だけですけどね。。。)
後は画面の要素となる各オブジェクトに対する操作を覚えていくと幅が広がります。

さて次回以降はJavaのことや、eclipseのことに触れていきます。
(Javaわかんないと元も子もないからねぇ~)

2012年3月1日木曜日

【Forest君用】TextViewを動的に表示させる方法

「Hello World!」アプリを3度に渡って説明してきましたが、
今回はより実践に近いコーディングをしていきます。

「Hello World!」アプリではTextViewを使用してstring.xmlで
設定した文字列を表示させていました。
勿論、string.xmlに設定する値を変えたら画面の表示も変わります。

それでは次のケースはどうでしょう?
  1. 画面にボタンが2個あり、押したボタンによって表示する文字を変える
  2. 画面に文字入力できるテキストボックスがあり、入力された文字を画面に表示する
  3. 画面が2つ用意されており、1つ目の画面でリストから選択された項目を2つ目の画面で表示する
実際の開発では固定値として文字列を用意することはありますが、
必ずしも万能ではありません。
上記ケースの実装方法を考えてみてください。
string.xmlだけでは難しいことがわかると思います。

上記を踏まえて、Javaソース内でTextViewの文字列を設定する方法を勉強していきます。

package jp.gr.java_conf.siroco.helloandroid;

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

public class HelloAndroidActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // TextViewインスタンス生成
        TextView textView = new TextView(this);

        // 表示するテキストの設定
        textView.setText("STAND ALONE COMPLEX");

        // ActivityにViewを設定
        setContentView(textView);

//        setContentView(R.layout.main);
    }
}

これは前回までで作った「HelloAndroidActivity」を元に作っています。
変更したのは13行目以降。

まず14行目でTextViewクラスのインスタンスを生成します。
(xmlファイルで定義していたTextViewは、ソース中ではクラスとして使用できます)

次に17行目、setTextメソッドで画面に表示する文字列を設定します。

最後に20行目でTextViewをActivityに設定します。

実行すると"STAND ALONE COMPLEX"と表示されるはずです。
(最近、甲殻機動隊を見てたから。。。)


因みに今回表示している画面は、
前回の「HelloAndroidActivity」画面とは全く違うものです。
その説明は、また次回。