ApiDemosを調べる1 - 初期Activityの表示
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); String path = intent.getStringExtra("com.example.android.apis.Path"); if (path == null) { path = ""; } setListAdapter(new SimpleAdapter(this, getData(path), android.R.layout.simple_list_item_1, new String[] { "title" }, new int[] { android.R.id.text1 })); getListView().setTextFilterEnabled(true); }
ここではpathにnullが返ってくるので、path=""が実行される。
setListAdapter()を用いて、ListにAdapterを設定する。
ここではSimpleAdapter()を用いている。
解説はコンピュータクワガタさんへ
第2引数に、リストに列挙するデータを渡す。
第3引数は、リストの書式(xml)、第4引数はデータのキー、
第5引数にはキーに対する書式(xml)を記述する。
getDataの中身は以下のとおり。
protected List getData(String prefix) { List<Map> myData = new ArrayList<Map>(); Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE); PackageManager pm = getPackageManager(); List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0); if (null == list) return myData; String[] prefixPath; if (prefix.equals("")) { prefixPath = null; } else { prefixPath = prefix.split("/"); } int len = list.size(); Map<String, Boolean> entries = new HashMap<String, Boolean>(); for (int i = 0; i < len; i++) { ResolveInfo info = list.get(i); CharSequence labelSeq = info.loadLabel(pm); String label = labelSeq != null ? labelSeq.toString() : info.activityInfo.name; if (prefix.length() == 0 || label.startsWith(prefix)) { String[] labelPath = label.split("/"); String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length]; if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) { addItem(myData, nextLabel, activityIntent( info.activityInfo.applicationInfo.packageName, info.activityInfo.name)); } else { if (entries.get(nextLabel) == null) { addItem(myData, nextLabel, browseIntent(prefix.equals("") ? nextLabel : prefix + "/" + nextLabel)); entries.put(nextLabel, true); } } } } Collections.sort(myData, sDisplayNameComparator); return myData; }
- Intentを用いて、Activityを取得する。
- Activityのパスを編集(app.Helloworldからappのみ取り出す)
- myDataに名前とIntentを格納する(addItem()。この時Intentにprefix情報を付加しておく)
最後に、ここで設定したAdapterを設定する(setListAdapter())ことで、
List表示されるようになる。
Listをクリックすると、別なActivityが開く。
それを実装しているのが以下。
@Override protected void onListItemClick(ListView l, View v, int position, long id) { Map map = (Map) l.getItemAtPosition(position); Intent intent = (Intent) map.get("intent"); startActivity(intent); } }
- クリックすると、onListItemClick()に飛んでくる(コールバック関数)
- ListViewの中のデータを取得するためにはgetListView().getItemAtPosition(position)する
- ここでは、先に設定したIntentを取得する。
- intentで指定されたActivityへ遷移する
→apisをクリックすると以下のIntentが選択される
つまり、またこのActivityのonCreateに遷移する。
2回目に呼び出された場合、onCreateの
String path = intent.getStringExtra("com.example.android.apis.Path");
の部分にpathが入力される。ここにはクリックされたアイテム
の名前が入る。
2回目のonCreateではそのクリックされたアイテム以下の
階層にのみアクセスして、ListViewに表示する。
ここで、改めてAndroidManifest.xmlの一部を見てみると、
android:label="Graphics/OpenGL ES/Frame Buffer Object" android:label="Graphics/OpenGL ES/Cube Map"
といったlabelがある。
最初にGraphicsをクリックするとGraphics以下のものがListとして表示され、
OpenGL ESをクリックすると、それ以下のもの(たとえばFrame Buffer Object)
表示される。
最後に、Frame Buffer Objectをクリックすると、該当のActivityに
アクセスできるIntentを取得して、startActivityする、
という流れのようです。
個別のActivityについては省略。