2011年11月30日水曜日

東方神霊廟

たまにはAndroid以外の事も。

以前少し触れたけど、sirocoはゲームを作りたかった事がありました。
無理だったけどね。。。
(まだ諦めてないよ)

ゲームは子供のころから好きで、今でも少しやっています。
最近やっているのは東方Projectの最新作「東方神霊廟」。
紅魔卿からずっとやってきたけど、sirocoはへたっぴいなので
Nomalノーコンテニュークリアした事なかったのです。

けれど、先日、とうとうやりました!
ノーコンクリアです!!
勿論Nomalですが、sirocoにとっては凄い事です!
感激で、エンディング中はずっと震えてました。。。

あまりに嬉しかったので、アプリ関係ないけど、
載せちゃいました(^ - ^;)

2011年11月28日月曜日

PreferenceActivityを使用した設定画面

以前予告した通り、設定画面の作り方について学習していきます。

設定画面は大抵のアプリケーションに用意されていて、
sirocoのアプリにも、勿論、用意するつもりです。

設定画面の作成方法は色々とありますが、
PreferenceActivityを使った、最もシンプルな方法を紹介します。

今回は先に実行結果。

上記imageの通り、
「チェックボックス」、「エディットテキスト」、「リスト」、「リングストン」を表示します。
それぞれの要素が次の"res/layout/preference.xml"の各タグに紐付いています。
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
 xmlns:android="http://schemas.android.com/apk/res/android">
 <PreferenceCategory android:title="@string/title">
  <CheckBoxPreference
   android:key="checkbox_key"
   android:title="@string/checkbox_title"
   android:summary="@string/checkbox_summary" />
  <EditTextPreference
   android:key="edittext_key"
   android:title="@string/edittext_title"
   android:summary="@string/edittext_summary"
   android:dialogTitle="@string/edittext_dialog_title" />
  <ListPreference
   android:key="list_key"
   android:title="@string/list_title"
   android:summary="@string/list_summary"
   android:dialogTitle="@string/list_dialog_title"
   android:entries="@array/list_entries"
   android:entryValues="@array/list_entry_values" />
  <RingtonePreference
   android:key="ringtone_key"
   android:title="@string/ringtone_title"
   android:showDefault="true"
   android:summary="@string/ringtone_summary" />
 </PreferenceCategory>
</PreferenceScreen>

05行目:CheckBoxPreferenceタグがチェックボックスに、
09行目:EditTextPreferenceタグがエディットテキストに、
14行目:ListPreferenceタグがリストに、
21行目:RingtonePreferenceタグがリングストンに対応します。

綺麗な入れ子になっているので、理解しやすいと思います。

次は画面に表示する文字列と、リストの要素関連のxmlファイルです。
"res/values/strings.xml"
<?xml version="1.0" encoding="utf-8"?>
<resources>
 <string name="app_name">preferenceSample</string>
    <string name="title">設定画面Sample</string>
    <string name="checkbox_title">Checkbox</string>
    <string name="checkbox_summary">CheckboxのSummary</string>
    <string name="edittext_title">EditText</string>
    <string name="edittext_summary">EditTextのSummary</string>
    <string name="edittext_dialog_title">
        EditTextのダイアログタイトル
    </string>
    <string name="list_title">List</string>
    <string name="list_summary">ListのSummary</string>
    <string name="list_dialog_title">Listのダイアログタイトル</string>
    <string name="ringtone_title">Ringtone</string>
    <string name="ringtone_summary">RingtoneのSummary</string>
</resources>

"res/values/arrays.xml"
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="list_entries">
        <item>First</item>
        <item>Second</item>
        <item>Third</item>
    </string-array>
    <string-array name="list_entry_values">
        <item>FirstのValue</item>
        <item>SecondのValue</item>
        <item>ThirdのValue</item>
    </string-array>
</resources>

最後にJavaコード。
addPreferencesFromResourceメソッドで
設定画面の項目を定義したxmlファイル(preference.xml)を指定しているだけです。
import android.os.Bundle;
import android.preference.PreferenceActivity;

public class PreferenceSample01 extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.layout.preference);
    }
}

表示された要素をタップした様子は次の通りです。



大半がxmlファイルの設定で行える為、手軽に作成が出来ます。
実際のアプリの設定画面では、そのアプリに適した内容をpreference.xmlに設定するわけです。
sirocoの場合、カメラアプリを作成しようとしているので、
フラッシュのon/offの切り替えや、画面サイズなどを定義するのかな~

PreferenceActivityについては、あと何度か学習して、
より実践的な設定画面を作ってみたいと思います。

2011年11月22日火曜日

ListViewの折り畳み

ListViewについて色々とやってきましたが、今回で最後にします。

ListViewはリストを画面に表示するクラスでしたが、
リストを選択すると更にリストが表示される、
階層表示を実装してみます。

まずはJavaのコードです。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.Toast;

public class ListView11 extends Activity{

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  // ExpandableListViewインスタンスを取得
  ExpandableListView listView =
    (ExpandableListView) findViewById(R.id.list);

  // 親のリストを格納するArrayListインスタンスを生成
  List<Map<String, Object>> parentsList =
    new ArrayList<Map<String, Object>>();

  // parentsListにデータを追加
  parentsList.add(getParentData("親1"));
  parentsList.add(getParentData("親2"));

  // 子のリストを格納するArrayListインスタンスを生成
  List<List<Map<String, Object>>> childrenList =
    new ArrayList<List<Map<String, Object>>>();

  // 子リストにデータを追加
  childrenList.add(getChildList("子1-1", "子1-2")); // 親1に対応
  childrenList.add(getChildList("子2-1", "子2-2")); // 親2に対応

  // SimpleExpandableListAdapterインスタンスを生成
  SimpleExpandableListAdapter adapter = new SimpleExpandableListAdapter(
    this,
    parentsList,
    android.R.layout.simple_expandable_list_item_1,
    new String[]{"parent_text"},
    new int[]{android.R.id.text1},
    childrenList,
    R.layout.row,
    new String[]{"child_text"},
    new int[]{R.id.child_text}
  );

  // 作成したアダプタをExpandableListViewにセットする
  listView.setAdapter(adapter);

  // クリック時のリスナを設定
  listView.setOnChildClickListener(
    new ExpandableListView.OnChildClickListener() {

   @SuppressWarnings("unchecked") // ジェネリクスを使用したキャストの為
   @Override
   public boolean onChildClick(
     ExpandableListView parent,
     View view,
     int groupPosition,
     int childPosition,
     long id) {

    // アダプタからデータを取得してトーストで表示
    ExpandableListAdapter adapter = parent.
      getExpandableListAdapter();
    Map<String, Object> childMap = (Map<String, Object>)adapter.
      getChild(groupPosition, childPosition);
    Toast.makeText(
      ListView11.this,
      childMap.get("child_text").toString(),
      Toast.LENGTH_SHORT
    ).show();
    return false;
   }
  });
 }

 /**
  * 親リストに格納するデータを返す
  *
  * @param object  親リストに格納するMapのvalue値
  * @return parentData 親リストに格納するMap
  */
 private Map<String, Object> getParentData(Object object) {
  Map<String, Object> parentData = new HashMap<String, Object>();
  parentData.put("parent_text", object);
  return parentData;
 }

 /**
  * 子リストに格納するデータを返す
  *
  * @param object  子リストに格納するMapのvalue値の配列
  * @return childList 子リストに格納するList
  */
 private List<Map<String, Object>> getChildList(Object... object) {
  List<Map<String, Object>> childList =
    new ArrayList<Map<String, Object>>();

  // 引数に渡されたオブジェクトの数だけ子リストを追加
  for (Object o : object) {
   Map<String, Object> childData = new HashMap<String, Object>();
   childData.put("child_text", o);
   childList.add(childData);
  }
  return childList;
 }
}
長ったるいコードですが、やっている事は単純です。

1. ExpandableListViewクラスのインスタンスを生成(22行目)
⇒これが画面に表示されるリストの骨格です。
名前の通りListViewを継承しています。

2. SimpleExpandableListAdapterクラスのインスタンスを生成(42行目)
⇒ExpandableListViewに値をセットする為のアダプタ。
親リストと子リストをコンストラクタで渡してやる事で、
階層表示を可能にします。

3. ExpandableListViewにSimpleExpandableListAdapterをセット(55行目)
⇒作成したアダプタをリストビューに設定する事で、
親リストと子リストが格納されます。

その他にクリックリスナーを設定していたり、
privateなメソッドで親リストや子リストの生成を行っていますが、
今回の主題であるリストの階層表示には直接関係ありません。。。

続いて"res/layout/main.xml"のコードです。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/parent"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>
<ExpandableListView
    android:id="@+id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
/>
</LinearLayout>
ここで設定しているExpandableListViewが親リストとなります。

"res/layout/row.xml"のコードです。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
>
<TextView
    android:id="@+id/child_text"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
/>
</LinearLayout>
TextViewが子リストの要素となります。


上記のコードを実行すると、次のように表示されます。

親リストをタップする事で子リストが表示されます。

今回は親リストに対して、子リストを2件ずつ設定しましたが、
子リストにあたるArrayListの要素数だけ表示する事が可能です。


ListViewを4回程学習してきましたが、
各パターンごとに専用のアダプタが用意されており、
使い方さえわかれば初心者のsirocoでも実装は難しくないと感じました。

色々なAPIが用意されているのもAndroidの良いところですね~
次回はアプリには大抵用意されている「設定画面」を作ってみたいと思います。

2011年11月18日金曜日

ListViewの複数行選択

ListViewのコードを載せるのも、もう3回目。
だいぶ慣れてきました。
今回はリストを複数選択できるようにします。

ポイントとなるのは次の3点です。

  • android.R.layout.simple_list_item_multiple_choice
    Javaソースの26行目です。
    これをArrayAdapterのコンストラクタに渡すことで、チェックボックスが表示されます。
  • setChoiceMode(ListView.CHOICE_MODE_MULTIPLE)
    Javaソースの37行目です。
     コメントにある通り、これを実行する事で複数選択が可能となります。
  • android:choiceMode="multipleChoice"
    xmlの方の11行目。
    ここでも複数選択を指定してやります。
Javaコードは以下の通り
import android.app.Activity;
import android.os.Bundle;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class ListView03 extends Activity implements OnItemClickListener{

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  // ListViewで表示するデータを作成
  for (int i = 0; i < mWords.length; i++) {
    mWords[i] = String.valueOf(i);
  }

  // リストアダプタを作成
  ArrayAdapter<String> adapter = new ArrayAdapter<String>(
    this,
    android.R.layout.simple_list_item_multiple_choice,
    mWords);

  // リストアダプタをリストビューにセット
  mListView = (ListView) findViewById(R.id.listview);
  mListView.setAdapter(adapter);

  // ListView内部のViewがフォーカス出来ないようにする
  mListView.setItemsCanFocus(false);

  // 複数選択可能にする
  mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

  // クリックイベントを取得
  mListView.setOnItemClickListener(this);
 }

 @Override
 public void onItemClick(
   AdapterView<?> parent,
   View view,
   int position,
   long id) {

  // 選択状態を取得する
  SparseBooleanArray checked = mListView.getCheckedItemPositions();

  // 選択された要素をトーストで表示
  String word = "";
  for (int i = 0; i < mWords.length; i++) {
   word += mWords[i] +
     ":" +
     checked.get(i) +
     System.getProperty("line.separator");
  }
  Toast.makeText(this, word, Toast.LENGTH_LONG).show();
 }

 private ListView mListView;
 private String[] mWords = new String[10];
}
"res/layout/main.xml"のコードは以下の通り
<linearlayout
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android"
>
<listview
    android:id="@+id/listview"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    android:choicemode="multipleChoice"
>
</linearlayout>

AndroidManifest.xmlは割愛します(いつもと一緒だから。。。)。


リストをクリックするとToastが表示されます。
(チェックボックスが選択されているのがTrueになってます。)

2011年11月15日火曜日

ListViewにImageを表示

前回はListViewで各行にテキストを表示させましたが、
今回は複数のテキストやイメージ画像を表示させてみます。

複数の要素をListViewの各エントリに設定する必要がある為、
アダプタにはSimpleAdapterを使用します。
(実際のコードでは SimpleAdapterを拡張したクラスを使用しています。)

Javaコードは以下の通り
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class ListView02 extends Activity{

 // リストビューに表示する文字列1
 String[] mCode = {
   "001", "002", "003", "004", "005"};

 // リストビューに表示する文字列2
 String[] mName = {
   "Itiro", "Jiro", "Saburo", "Siro", "Goro"};

 // リストビューに表示するImage用配列のインスタンス生成
 int[] mIcon = new int[5];


 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  // Image用配列にリソースIDを設定
  for (int i = 0; i < 5; i++) {
   mIcon[i] = R.drawable.icon;
  }

  // データを格納するためのArrayListを宣言
  List<HashMap<String, Object>> data =
   new ArrayList<HashMap<String, Object>>();

  for (int i = 0; i < 5; i++) {
   HashMap<String, Object> map = new HashMap<String, Object>();

   map.put("code", mCode[i]);
   map.put("name", mName[i]);
   map.put("icon", mIcon[i]);

   // 作成したmapをリストに追加
   data.add(map);
  }

  // 作成したdataとカスタマイズしたレイアウト「row.xml」を
  // 紐付けたCustomAdapterを作成する
  CustomAdapter customAdapter = new CustomAdapter(
    this,
    data,
    R.layout.row,
    new String[]{"code", "name"},
    new int[]{R.id.code, R.id.name}
  );

  // 「main.xml」のListViewにSimpleAdapterをセットする
  ListView listView = (ListView) findViewById(R.id.listview);
  listView.setAdapter(customAdapter);
 }


 // SimpleAdapterを継承したCustomAdapterを作成
 public class CustomAdapter extends SimpleAdapter {
  LayoutInflater mLayoutInflater;

  // コンストラクタ
  public CustomAdapter(
    Context context,
    List<? extends Map> data,
    int resource,
    String[] from,
    int[] to) {
   super(context, data, resource, from, to);
  }

  @SuppressWarnings("unchecked") // ジェネリクスを使用したキャストの為
  @Override
  public View getView(
    int position, 
    View convertView, 
    ViewGroup parent) {
   mLayoutInflater = LayoutInflater.from(getBaseContext());

   // レイアウトにrow.xmlを紐付ける
   convertView = mLayoutInflater.inflate(R.layout.row, parent, false);
   ListView listView = (ListView) parent;

   // 該当する位置のデータを取得する
   Map<String, Object> data = (Map<String, Object>) listView.
    getItemAtPosition(position) ;

   // 文字入れつ1をTextViewにセットする
   TextView code = (TextView) convertView.
    findViewById(R.id.code);
   code.setText((String) data.get("code"));

   // 文字列2をTextViewにセットする
   TextView name = (TextView) convertView.
    findViewById(R.id.name);
   name.setText((String) data.get("name"));

   // アイコンをImageViewにセットする
   ImageView icon = (ImageView) convertView.
    findViewById(R.id.icon);
   icon.setImageResource((Integer) data.get("icon"));

   return convertView;
  }
 }
}

CustomAdapterクラスではListViewの要素として
row.xmlファイルの定義されたビュー情報を設定しています。

ListViewクラスでは、
表示画面の各行に表示されるテキスト&イメージをHashMapでマッピングし、
ArrayListに格納しています。
更に、HashMapを要素に持つArrayListを引数に、CustomAdapterインスタンスを生成し、
表示画面であるListViewにセットしています。


"res/layout/main.xml"のコードは以下の通り
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>
<ListView
    android:id="@+id/listview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
/>
</LinearLayout>


"res/layout/row.xml"のコードは以下の通り
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="60dip"
>
<ImageView
    android:id="@+id/icon"
    android:layout_width="60dip"
    android:layout_height="70dip"
    android:src="@drawable/icon"
/>
<TextView
    android:id="@+id/code"
    android:layout_width="100dip"
    android:layout_height="wrap_content"
/>
<TextView
    android:id="@+id/name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
/>
</LinearLayout>

Listの各エントリ(ビューの1行)に設定する内容を示しています。
1行目・・・ImageView id:icon
2行目・・・TextView id:code
3行目・・・TextView id:name

上記コードで実行すると、以下の様にリスト画面にイメージが表示されます。


ListViewにイメージが表示されました。

2011年11月13日日曜日

ListViewの表示

少し開発っぽい事も書いてみます。

ListViewについて。
ListViewとは、Androidでリストを表示させる場合に使用するクラスで、
よく使われるクラスの一つです。

今回はArrayAdapterクラスを使用してリスト表示する、
一般的なパターンを行ってみました。

Javaコードは以下の通り
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class ListView01 extends Activity {

 // リストビューに表示するデータ
 String[] mLists = {
   "aaa", "bbb", "ccc", "ddd", "eee",
   "fff", "ggg", "hhh", "jjj", "iii"};

 @Override
 public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // アダプタを用意して配列mListsを紐付ける
        ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(
          this,
          android.R.layout.simple_list_item_1,
          mLists);

        // main.xmlで定義したListViewにlistAdapterを設定
        ListView listView = (ListView) findViewById(R.id.listview);
        listView.setAdapter(listAdapter);
    }
}

"res/layout/main.xml"のコードは以下の通り
<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
> 
<ListView
    android:id="@+id/listview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
/> 
</LinearLayout> 

上記コードで実行すると、リスト画面が表示されます。


今回はテキストのみの表示でしたが、imageなどを表示させる事も可能です。

2011年11月10日木曜日

ドット絵とsirocoの由来

sirocoは趣味でドット絵をやっています。

ドット絵とはゲーム(FCとかSFC)とかで良く使われていた技法で、
1ピクセルずつ点(ドット)を打っていって絵にする事を言います。

最近はしてなかったけど、Blogを初めて、
「幻夢桜白子」の名前を使う事にしたから、
久々にやってみました。

← siroco

こんな感じ。
見たらイメージがわく人もいると思います。

ついでに言うと、「幻夢桜白子」って名前はゲームの主人公に使いたかったものです。
ゲーム作る腕前は無かったので(まだ諦めてないけれど)、自分の名前として使っちゃいました(^ - ^;)

コーディングもドット絵も初心者ですが、
色々と好奇心をもって挑戦していこうと思います。

2011年11月7日月曜日

パッケージ名の取得について

sirocoはAndroidアプリの公開を考えている為、
パッケージ名の取得を考えました。

Javaでは所属企業のドメイン名をトップレベルドメイン側から並べ替えて
パッケージ名にする方法が推奨されています。
sirocoの様に個人で開発をする場合、個人ドメインを持っている事は稀でしょうから、
「パッケージ名登録/利用サービス」と言うものを紹介します。

「パッケージ名登録/利用サービス」とは、Java カンファレンスのドメイン名 (java-conf.gr.jp)を
パッケージに利用する事が出来ます。
java-conf.gr.jp.XXXXXX(XXXXXXは任意の文字列)の様な感じ。

登録方法をメモしておきますので、これからアプリを公開前提で開発しようとしている人は、
参考にしてみてください。

日本インターネット協会のパッケージ名登録ページを開きます。
Step1:で、"登録"を選択して、"Next"ボタンをクリック。

Step2:で、必須事項の"パッケージ名"、"メールアドレス"、"登録者指名を"入力して
"Finish"ボタンをクリック。
因みに"登録者指名"は本名でなくてもOK見たいです(推奨は本名です)。

ここまでで仮登録が完了です。
記入したメールアドレスにメールが届いているはずなので、そちらを確認。

メール本文内のリンクから、認証ページへ。
"パッケージ名"と"認証コード"を入力して"Finish"ボタンをクリック。
("認証コード"はメール本文に記述されています。)

以上でパッケージ名の登録完了です。

2011年11月6日日曜日

最初に作るアプリは・・・

sirocoはAndroidアプリ開発の初心者ですが、作りたいアプリは既に決まっています。
カメラ機能を使用したアプリで、アプリ名は「閃きカメラ」。
詳細の機能は今のところ秘密です。

名前の通り、カメラアプリになります。
今後はアプリ関連のメモを"Apps"ラベルに残していこうと思います。

(基礎の学習内容は"Development"ラベルに残していきます。)

2011年11月4日金曜日

使っている本




sirocoはAndroid開発初心者の為、書物を使って学習しています。
現在使用しているのは「AndroidSDK逆引きハンドブック」。

各操作(マップ、カメラ、等々)毎にChapter分けされていて、サンプルソースが多いのが特徴です。
sirocoの場合、前々から作りたいアプリのイメージが決まっていたので、この本を選びました。

実際に使ってみると、作りたいものにマッチする部分はいいのですが、Activityなどの基本的な部分の説明が少なく、最初の学習には不向きな様です。

今週末に別の本を買うつもりなので、併せて学習していきます。

実際に学習したソースのupは、それ以降になるかな。。。

2011年11月3日木曜日

開発の記録開始

はじめまして幻夢桜 白子(ユメサクラ シロコ)と言います。
名前が長いのでsirocoと書きます。

Androidアプリの開発を始めましたので、記録を残します。
基本的には自分の為の覚え書きとなりますが、
sirocoも他の方のブログを参考にする事があるので、
参考になるようでしたら使って下さい。