第二篇:http://blog.csdn.net/mapdigit/article/details/7555404 创建好ApiDemos项目以后,首先在模拟器上运行该程序,可以看到主界面是一个列表。单击列表中一个栏目后还有若干级列表,最终是一个Activity,展示了其API的一个特性。API Demos全面展示了系统的功能,包括界面、控件、图像处理和媒体处理等。
然后逐个来分析代码:
首先我们去AndroidManifest.xml文件中查看下app的入口,
1<activity android:name=".app.HelloWorld" android:label="@string/activity_hello_world"> 2 <intent-filter> 3 <action android:name="android.intent.action.MAIN" /> 4 <category android:name="android.intent.category.SAMPLE_CODE" /> 5 </intent-filter> 6 </activity>
android.R.layout_simple_list_item_1是android系统自带的资源文件,位于 / frameworks / base / core / res / res / layout / simple_list_item_1.xml
1<?xml version="1.0" encoding="utf-8"?> 2<!-- Copyright (C) 2006 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<TextView xmlns:android="http://schemas.android.com/apk/res/android" 18 android:id="@android:id/text1" 19 android:layout_width="match_parent" 20 android:layout_height="wrap_content" 21 android:textAppearance="?android:attr/textAppearanceListItemSmall" 22 android:gravity="center_vertical" 23 android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" 24 android:paddingRight="?android:attr/listPreferredItemPaddingRight" 25 android:minHeight="?android:attr/listPreferredItemHeightSmall" 26/> 可以看到该布局文件仅仅显示一个TextView,它的id为android.R.id.text1
1AbsListView.setTextFilterEnabled(true);
这个方法的作用是用来过滤选项的。例如在软键盘上打出一个a,则会过滤掉除了a开头的所有选项(在模拟器上可以看到效果,在真机上弹不出软键盘)。
1protected List<Map<String, Object>> getData(String prefix) { 2 List<Map<String, Object>> myData = new ArrayList<Map<String, Object>>(); 3 4 Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); 5 mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE); 6 7 PackageManager pm = getPackageManager(); 8 List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0); 9 10 if (null == list) 11 return myData; 12 13 String[] prefixPath; 14 String prefixWithSlash = prefix; 15 16 if (prefix.equals("")) { 17 prefixPath = null; 18 } else { 19 prefixPath = prefix.split("/"); 20 prefixWithSlash = prefix + "/"; 21 } 22 23 int len = list.size(); 24 25 Map<String, Boolean> entries = new HashMap<String, Boolean>(); 26 27 for (int i = 0; i < len; i++) { 28 ResolveInfo info = list.get(i); 29 CharSequence labelSeq = info.loadLabel(pm); 30 String label = labelSeq != null 31 ? labelSeq.toString() 32 : info.activityInfo.name; 33 34 if (prefixWithSlash.length() == 0 || label.startsWith(prefixWithSlash)) { 35 36 String[] labelPath = label.split("/"); 37 38 String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length]; 39 40 if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) { 41 addItem(myData, nextLabel, activityIntent( 42 info.activityInfo.applicationInfo.packageName, 43 info.activityInfo.name)); 44 } else { 45 if (entries.get(nextLabel) == null) { 46 addItem(myData, nextLabel, browseIntent(prefix.equals("") ? nextLabel : prefix + "/" + nextLabel)); 47 entries.put(nextLabel, true); 48 } 49 } 50 } 51 } 52 53 Collections.sort(myData, sDisplayNameComparator); 54 55 return myData; 56 }
知道列表的构成和响应后,我们接下来看看列表是如何被获取的,获取列表是在getData方法中,该方法获取的数据作为SimpleAdapter的参数,最终被ListActivity所使用。getData中有若干个重要的对象,如myData是我们需要获取的菜单列表数据;prefix是当前所处的目录,如果为空则为根目录; prefixPath是当前目录的列表,列表中包含了当前的每一级目录的内容;list是当前可以被执行的所有Activity列表。程序是怎么知道当前有哪些可以执行的Activity的呢?请看下面两行代码:
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
在java中,如果要对集合对象或数组对象进行排序,需要实现Comparator接口以达到我们想要的目标。
1private final static Comparator<Map<String, Object>> sDisplayNameComparator = 2 new Comparator<Map<String, Object>>() { 3 private final Collator collator = Collator.getInstance(); 4 5 public int compare(Map<String, Object> map1, Map<String, Object> map2) { 6 return collator.compare(map1.get("title"), map2.get("title")); 7 } 8 };
loadLabel() 查找顺序
1、先找activity的Lable, 如果没有找到则下一步
2、找application的Lable, 如果没有找到则下一步
3、找activity的name 名字一定会有的
它通过PackageManager 从 AndroidManifest.xml中读取所以Intent-Filter含有:Intent.ACTION_MAIN和Intent.CATEGORY_SAMPLE_CODE所有Activity信息。前面说过200多个示例根据其功能分类,比如 Hello World示例它的Label为
App/Activity/Hello World,
表示它的分类为分类App下Activity子类。
getData(String prefix)根据每个Activity的Label属性和当前层次(prefix)来决定当前列表中某项为叶子列表项,还是分类列表项,如果是叶子列表项,则添加为activityIntent,当用户点击改列表项时则会触发该示例。若是分类列表项,则添加为browseIntent,browseIntent还是触发ApiDemos Activity,但Intent带有Extra信息,表示需要显示改分类下的子类:
1protected Intent activityIntent(String pkg, String componentName) { 2 3 Intent result = new Intent(); 4 5 result.setClassName(pkg, componentName); 6 7 return result; 8 9 } 10 11
此时如果用户点击该节点列表项,则会进入该分类的下级目录。
1 @Override 2 @SuppressWarnings("unchecked") 3 protected void onListItemClick(ListView l, View v, int position, long id) { 4 Map<String, Object> map = (Map<String, Object>)l.getItemAtPosition(position); 5 6 Intent intent = (Intent) map.get("intent"); 7 startActivity(intent); 8 }
此外,ApiDemos还定义了ApiDemosApplication,该类继承了Application,如果需要在多个Activity共享一些数据,可以定义在Application中。
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 17package com.example.android.apis; 18 19import android.app.Application; 20 21/** *//** 22 * This is an example of a {@link android.app.Application} class. This can 23 * be used as a central repository for per-process information about your app; 24 * however it is recommended to use singletons for that instead rather than merge 25 * all of these globals from across your application into one place here. 26 * 27 * In this case, we have not defined any specific work for this Application. 28 * 29 * See samples/ApiDemos/tests/src/com.example.android.apis/ApiDemosApplicationTests for an example 30 * of how to perform unit tests on an Application object. 31 */ 32public class ApiDemosApplication extends Application { 33 @Override 34 public void onCreate() { 35 } 36} 37
可以看到该类什么都干。如果使用了自定义的Application,别忘了修改AndroidManifest.xml ,如下:
1<application android:name="ApiDemosApplication" 2 android:label="@string/activity_sample_code" 3 android:icon="@drawable/app_sample_code" 4 android:hardwareAccelerated="true"> 5 6</application>
最后我们看下Shakespeare这个常量类,
该类定义了两个字符串数组,这两个数组在以后会用到。
至此,com.example.android.apis包下的文件已经全部搞定了。
|
|
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
常用链接
留言簿
随笔分类
随笔档案
文章分类
搜索
最新评论
阅读排行榜
评论排行榜
|
|