Android ApiDemos 登顶之路(一)

江湖传言,只要学会ApiDemo宝典,就掌握了android开发的致胜之道。于是我信了,如果您也是一名新手,大家可以一起探讨共勉,如果您是大神请指点。
废话不多说我们先来解析第一篇:ApiDemos的主界面

  /**
 * 设计思想,这是ApiDemos的启动activity,它继承了ListActivity,列出了当前ApiDemos八大类别的名称,当我们点击
 * 某一类别后会进入相应的类别,并依次列出了该类目下的各个子类别,如果某一子类别是分类列表项则点击后会继续进入,如果子类别
 * 已经是叶子列表项,则点击后会启动该示例。
 * 
 *
 */
public class ApiDemos extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 当我们点击某一类目后,如果这个类目下面还有分类项,则通过再次启动自身的方式加载该类目下所有分类项的名称。并且在启动自身的同时
        // 将该类目的路径传递到新启动的activity当中。所以我们需要在这里获取由上一个activity传递过来的路径值。
        Intent intent = getIntent();

        String path = intent.getStringExtra("com.example.api.path");

        // 如果是第一次启动程序,paht==null
        if (path == null) {
            path = "";
        }

        /**
         * 使用simpleAdapter适配器为ListActivity加载数据 SimpleAdapter(Context context,
         * List<? extends Map<String, ?>> data, int resource, String[] from,
         * int[] to)
         * 其构造方法共有四个参数第一个上下文,第二个是数据集,数据集是一个list集合,这个集合的每一个元素是一个map集合或其子类
         * ,第三个参数是我们的
         * ListActivity第一个条目的布局id,这里使用的是系统提供的simple_list_item_1由一个TextView构成
         * ,其id为text1。第四个参数是要显示
         * 的数据列表组,这里只需要显示一列“title”,如果需要显示多列可以继续在数组中追加。第五个参数用来显示数据的组件的id
         * ,当然同样可以有多个组件。 这里就是系统定义的那个id为text1的textView。
         */
        setListAdapter(new SimpleAdapter(this, getDatas(path),
                android.R.layout.simple_list_item_1, new String[] { "title" },
                new int[] { android.R.id.text1 }));

        // 当listView获得焦点时,当用户输入快速查询的字符时,允许根据用户的输入字符筛选出匹配的列表项
        getListView().setTextFilterEnabled(true);
    }

    protected List<Map<String, Object>> getDatas(String prefix) {
        List<Map<String, Object>> datas = new ArrayList<Map<String, Object>>();


        // 从AndroidManifest.xml中筛选出所有apiDemo的activity信息
        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
        //为了与系统定义的类别相区别,这里随便定义了一个类别名称
        mainIntent.addCategory("COM_FISHTOSKY_CODE");

        PackageManager pm = getPackageManager();
        List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);

        if (list == null) {
            return datas;
        }
        // 定义一个字符串数组,用于存储将路径按“/”切割后的各个部分
        String[] prefixPath;
        // 存储加上“/”后的路径
        String prefixWithSlash = prefix;

        // 第一次启动prefix为“”
        if (prefix.equals("")) {
            prefixPath = new String[]{};
        } else {
            prefixPath = prefix.split("/");
            prefixWithSlash = prefix + "/";
        }

        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);
            // 获取activity的label对应的字符串,以hellowrold这个demo为例查看其label的值为:App/Activity/<b>Hello
            // <i>World</i></b>
            // <b>和<i>表示为字符设置属性<b>表示字符<i>表示字符为斜体
            String label = labelSeq != null ? labelSeq.toString()
                    : info.activityInfo.name;

            // 判断如果是第一次启动或者点击类目启动新的activity都可以满足条件
            if (prefixPath.length == 0 || label.startsWith(prefixWithSlash)) {
                String[] labelPath = label.split("/");
                String nextLabel = prefixPath.length == 0 ? labelPath[0]
                        : labelPath[prefixPath.length];

                // 将下一级目录中的内容展示出来
                if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) {
                    addItem(datas,nextLabel,activityIntent(
                    info.activityInfo.applicationInfo.packageName,info.activityInfo.name));
                } else {
                    // 判断是否忆经存在该类目
                    if (entries.get(nextLabel) == null) {
                        addItem(datas, nextLabel,
                                browseIntent(prefix.equals("") ? nextLabel
                                        : prefix + "/" + nextLabel));
                        entries.put(nextLabel, true);
                    }
                }
            }
        }

        // 对集合进行排序
        Collections.sort(datas, sDisplayNameComparator);
        return datas;
    }

    // 定义一个排序器
    private static final Comparator<Map<String, Object>> sDisplayNameComparator = new Comparator<Map<String, Object>>() {
        //拿到一个比较器实例
        private final Collator collator=Collator.getInstance();
        @Override
        public int compare(Map<String, Object> map1, Map<String, Object> map2) {
            return collator.compare(map1.get("title"),map2.get("title"));
        }
    };

    /**
     * 分类项列表
     * 
     * @param string
     *            路径名
     * @return
     */
    private Intent browseIntent(String path) {
        Intent result = new Intent(this, ApiDemos.class);
        result.putExtra("com.example.api.path", path);
        return result;
    }

    /**
     * 叶子项列表
     * 
     * @param packageName
     *            包名
     * @param activityName
     *            类名
     * @return
     */
    private Intent activityIntent(String packageName, String activityName) {
        Intent result = new Intent();
        result.setClassName(packageName, activityName);
        return result;
    }

    /**
     * 向数据集中添加内容
     * @param datas 数据集
     * @param name 当前界面要展示的示例的title
     * @param intent 点击条目时启动下一个界面的intent
     */
    private void addItem(List<Map<String, Object>> datas, String name,
            Intent intent) {
        Map<String, Object> temp = new HashMap<String, Object>();
        temp.put("title", name);
        temp.put("intent", intent);
        datas.add(temp);
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        Map<String, Object> map=(Map<String, Object>) l.getItemAtPosition(position);
        Intent intent=(Intent) map.get("intent");
        startActivity(intent);
    }
}

配置文件中只需改动:

<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Black" >
        <activity
            android:name=".ApiDemos"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity 
            android:name="com.example.apidemos.HelloWord"
            android:label="@string/activity_hello_world" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="COM_FISHTOSKY_CODE"/>
            </intent-filter>
        </activity>
    </application>

新建helloword的activity,我们不需要编写任何代码,只需在其string.xml下添加
一行App/Activity/Hello World即可

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值