android ApiDemos学习1 主界面动态ListView显示
0?Android提供了一個供開發者學習使用的示例程序。其界面如下。圖中可以看到,應用列表應為ListView,看其源碼發現,并非為簡單的ListView,而是采用動態加載的方式。
? ? ? ? ? ??
1 主界面代碼如下:
ApiDemos 1 /*2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.example.android.apis;
18
19 import android.app.ListActivity;
20 import android.content.Intent;
21 import android.content.pm.PackageManager;
22 import android.content.pm.ResolveInfo;
23 import android.os.Bundle;
24 import android.view.View;
25 import android.widget.ListView;
26 import android.widget.SimpleAdapter;
27
28 import java.text.Collator;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.Comparator;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35
36 public class ApiDemos extends ListActivity {
37
38 @Override
39 public void onCreate(Bundle savedInstanceState) {
40 super.onCreate(savedInstanceState);
41
42 Intent intent = getIntent();
43 String path = intent.getStringExtra("com.example.android.apis.Path");
44
45 if (path == null) {
46 path = "";
47 }
48
49 setListAdapter(new SimpleAdapter(this, getData(path),
50 android.R.layout.simple_list_item_1, new String[] { "title" },
51 new int[] { android.R.id.text1 }));
52 getListView().setTextFilterEnabled(true);
53 }
54
55 protected List getData(String prefix) {
56 List<Map> myData = new ArrayList<Map>();
57
58 Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
59 mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
60
61 PackageManager pm = getPackageManager();
62 List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
63
64 if (null == list)
65 return myData;
66
67 String[] prefixPath;
68
69 if (prefix.equals("")) {
70 prefixPath = null;
71 } else {
72 prefixPath = prefix.split("/");
73 }
74
75 int len = list.size();
76
77 Map<String, Boolean> entries = new HashMap<String, Boolean>();
78
79 for (int i = 0; i < len; i++) {
80 ResolveInfo info = list.get(i);
81 CharSequence labelSeq = info.loadLabel(pm);
82 String label = labelSeq != null
83 ? labelSeq.toString()
84 : info.activityInfo.name;
85
86 if (prefix.length() == 0 || label.startsWith(prefix)) {
87
88 String[] labelPath = label.split("/");
89
90 String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length];
91
92 if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) {
93 addItem(myData, nextLabel, activityIntent(
94 info.activityInfo.applicationInfo.packageName,
95 info.activityInfo.name));
96 } else {
97 if (entries.get(nextLabel) == null) {
98 addItem(myData, nextLabel, browseIntent(prefix.equals("") ? nextLabel : prefix + "/" + nextLabel));
99 entries.put(nextLabel, true);
100 }
101 }
102 }
103 }
104
105 Collections.sort(myData, sDisplayNameComparator);
106
107 return myData;
108 }
109
110 private final static Comparator<Map> sDisplayNameComparator = new Comparator<Map>() {
111 private final Collator collator = Collator.getInstance();
112
113 public int compare(Map map1, Map map2) {
114 return collator.compare(map1.get("title"), map2.get("title"));
115 }
116 };
117
118 protected Intent activityIntent(String pkg, String componentName) {
119 Intent result = new Intent();
120 result.setClassName(pkg, componentName);
121 return result;
122 }
123
124 protected Intent browseIntent(String path) {
125 Intent result = new Intent();
126 result.setClass(this, ApiDemos.class);
127 result.putExtra("com.example.android.apis.Path", path);
128 return result;
129 }
130
131 protected void addItem(List<Map> data, String name, Intent intent) {
132 Map<String, Object> temp = new HashMap<String, Object>();
133 temp.put("title", name);
134 temp.put("intent", intent);
135 data.add(temp);
136 }
137
138 @Override
139 protected void onListItemClick(ListView l, View v, int position, long id) {
140 Map map = (Map) l.getItemAtPosition(position);
141
142 Intent intent = (Intent) map.get("intent");
143 startActivity(intent);
144 }
145
146 }
?下面為部分配置文件代碼:
Manifest.xml <?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2007 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Declare the contents of this Android application. The namespace
attribute brings in the Android platform namespace, and the package
supplies a unique name for the application. When writing your
own application, the package name must be changed from "com.example.*"
to come from a domain that you own or have control over. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.apis">
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.NFC" />
<!-- For android.media.audiofx.Visualizer -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- We will request access to the camera, saying we require a camera
of some sort but not one with autofocus capability. -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<application android:name="ApiDemosApplication"
android:label="@string/activity_sample_code"
android:icon="@drawable/app_sample_code" >
<!-- This is how we can request a library but still allow the app
to be installed if it doesn't exist. -->
<uses-library android:name="com.example.will.never.exist" android:required="false" />
<activity android:name="ApiDemos">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- ************************************* -->
<!-- APPLICATION PACKAGE SAMPLES -->
<!-- ************************************* -->
<!-- Activity Samples -->
<activity android:name=".app.HelloWorld" android:label="@string/activity_hello_world">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter>
</activity>
<activity android:name=".app.DialogActivity"
android:label="@string/activity_dialog"
android:theme="@android:style/Theme.Dialog">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter>
</activity>
<activity android:name=".app.CustomDialogActivity"
android:label="@string/activity_custom_dialog"
android:theme="@style/Theme.CustomDialog">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter>
</activity>
<activity android:name=".app.QuickContactsDemo"
android:label="@string/quick_contacts_demo">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter>
</activity>
</application>
<instrumentation android:name=".app.LocalSampleInstrumentation"
android:targetPackage="com.example.android.apis"
android:label="Local Sample" />
</manifest>
2 分析
其想法主要分為以下幾步:
1) 給想要顯示在列表中的Activity分類
2) 然后從xml中根據分類標簽搜索出來
3) 將結果加載到List<Map>中
4) 據此list生成ListView并顯示
?
1) 想達到分類的效果,我們可以在Manifest.xml中對Activity做如下配置,稍后可根據category值進行過濾搜索。在自己的應用中,我們可以自定義category值。
<activity android:name=".app.HelloWorld" android:label="@string/activity_hello_world"><intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.SAMPLE_CODE"/>
</intent-filter>
</activity>
2)?根據category值查詢出想顯示的activity對應的ResolveInfo值列表。ResolveInfo對象包含Manifest.xml中對應Activity節點的所有信息,稍后可以根據這些信息對其進行加載。
mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
PackageManager pm = getPackageManager();
List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
?
? 3) 根據查詢出的activity的ResolveInfo list,生成List<Map>,其中Map包含title和intent
//10 得到父節點級別數組String[] prefixPath;
if (prefix.equals("")) {
prefixPath = null;
} else {
prefixPath = prefix.split("/");
}
int len = list.size();
Map<String, Boolean> entries = new HashMap<String, Boolean>();
//11 對過濾得到的ResolveInfo列表進行遍歷
for (int i = 0; i < len; i++) {
//111 得到ResolveInfo對象
ResolveInfo info = list.get(i);
CharSequence labelSeq = info.loadLabel(pm);
//112 根據ResolveInfo對象得到Activity對應的label信息,如App/Activity/Hello World
String label = labelSeq != null
? labelSeq.toString()
: info.activityInfo.name;
//113 判斷是否有子節點存在
if (prefix.length() == 0 || label.startsWith(prefix)) {
//114 得到字節點的層級數組,如{"App","Activity","Hello World"}
String[] labelPath = label.split("/");
//115 得到應顯示層級的標簽,如 App
String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length];
//116 當前節點無子節點,且不為第一個級別,將對應Activity信息和標簽信息組裝成intent,添加至List<Map>
if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) {
addItem(myData, nextLabel, activityIntent(
info.activityInfo.applicationInfo.packageName,
info.activityInfo.name));
} else {//116 當前節點有子節點或為第一級節點
//117 判斷是否在父節點數組中
if (entries.get(nextLabel) == null) {
//118 將當前activity和節點路徑信息一起組裝成intent,添加至List<Map>
addItem(myData, nextLabel, browseIntent(prefix.equals("") ? nextLabel : prefix + "/" + nextLabel));
//119 將此節點路徑加到父節點數組中
entries.put(nextLabel, true);
}
}
}
}
?
4) 根據List<Map>生成ListView
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);
轉載于:https://www.cnblogs.com/myparamita/archive/2011/10/31/2230777.html
總結
以上是生活随笔為你收集整理的android ApiDemos学习1 主界面动态ListView显示的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL is running but
- 下一篇: [android笔记]常用的Uri例子