zoukankan      html  css  js  c++  java
  • ApiDemos示例学习(1)——ApiDemos示例的导入

    ---恢复内容开始---

    今天准备开始写这个ApiDemos示例的学习日记了,放在网上以监督自己!

    首先是导入该示例。如果我们在配置Android开发环境是,利用Android SDK 安装包中的SDK Manager.exe文件下载完整的包,里面包含各种API版本的Samples,这里使用的是API 16版本中的ApiDemos。

    1、导入ApiDemos示例

      在eclipse中file->new->android sample project->next,然后在列出的不同版本示例中选择对应版本的ApiDemos示例即可导入示例。成功导入后,可以先看看该示例的结构,在运行该示例。示例结构如下:

    可以清楚的看到该工程的目录结构,程序的入口是com.example.android.apis包(这个可以在AndroidManifest.xml文件中查看)的ApiDemos.java文件中。该文件的功能是完成整个示例(包括示例下的所用小示例)的结构设计,十分巧妙,在Mono For Android 的示例包android-app-master包中同样采用相似的结构实现了示例导航的功能。

    现在具体分析一下该文件的功能:

      1 package com.example.android.apis;
      2 
      3 import android.app.ListActivity;
      4 import android.content.Intent;
      5 import android.content.pm.PackageManager;
      6 import android.content.pm.ResolveInfo;
      7 import android.os.Bundle;
      8 import android.view.View;
      9 import android.widget.ListView;
     10 import android.widget.SimpleAdapter;
     11 
     12 import java.text.Collator;
     13 import java.util.ArrayList;
     14 import java.util.Collections;
     15 import java.util.Comparator;
     16 import java.util.HashMap;
     17 import java.util.List;
     18 import java.util.Map;
     19 
     20 public class ApiDemos extends ListActivity {
     21 
     22     @Override
     23     public void onCreate(Bundle savedInstanceState) {
     24         super.onCreate(savedInstanceState);
     25         
     26         Intent intent = getIntent();
     27         String path = intent.getStringExtra("com.example.android.apis.Path");
     28         
     29         if (path == null) {
     30             path = "";
     31         }
     32 
     33         setListAdapter(new SimpleAdapter(this, getData(path),
     34                 android.R.layout.simple_list_item_1, new String[] { "title" },
     35                 new int[] { android.R.id.text1 }));
     36         getListView().setTextFilterEnabled(true);
     37     }
     38 
     39     protected List<Map<String, Object>> getData(String prefix) {
     40         List<Map<String, Object>> myData = new ArrayList<Map<String, Object>>();
     41 
     42         Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
     43         mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
     44         
     45         //通过PackageManager从AndroidManifest.xml中读取所有含有Intent.ACTION_MAIN
     46         //和Intent.CATEGORY_SAMPLE_CODE的所有Activity信息
     47         PackageManager pm = getPackageManager();
     48         List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
     49 
     50         if (null == list)
     51             return myData;
     52 
     53         String[] prefixPath;
     54         String prefixWithSlash = prefix;
     55         
     56         if (prefix.equals("")) {
     57             prefixPath = null;
     58         } else {
     59             prefixPath = prefix.split("/");
     60             prefixWithSlash = prefix + "/";
     61         }
     62         
     63         //变量len 记录了满足条件的Activity个数
     64         int len = list.size();
     65         
     66         Map<String, Boolean> entries = new HashMap<String, Boolean>();
     67 
     68         for (int i = 0; i < len; i++) {
     69             ResolveInfo info = list.get(i);//获取对应activity的ResolveInfo信息
     70             CharSequence labelSeq = info.loadLabel(pm);//获取对应activity的android:label属性值
     71             
     72             //如果为空,则label初始化为activity对应的android:name属性值,否则直接转换为string赋值给label
     73             String label = labelSeq != null
     74                     ? labelSeq.toString()
     75                     : info.activityInfo.name;//anctivityInfo.name对应于属性android:name
     76             
     77             if (prefixWithSlash.length() == 0 || label.startsWith(prefixWithSlash)) {
     78                 
     79                 String[] labelPath = label.split("/");
     80 
     81                 //prefixPath为空时,nextLabel值为labelPath第一个字符串;否则为labelPath中索引为prefixPath长度的值,不会造成越界因为
     82                 //prefixPath的最大长度永远比labelPath最大长度小1
     83                 String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length];
     84 
     85                 if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) {
     86                     addItem(myData, nextLabel, activityIntent(
     87                             info.activityInfo.applicationInfo.packageName,
     88                             info.activityInfo.name));
     89                 } else {
     90                     if (entries.get(nextLabel) == null) {
     91                         addItem(myData, nextLabel, browseIntent(prefix.equals("") ? nextLabel : prefix + "/" + nextLabel));
     92                         entries.put(nextLabel, true);
     93                     }
     94                 }
     95             }
     96         }
     97 
     98         Collections.sort(myData, sDisplayNameComparator);
     99         
    100         return myData;
    101     }
    102 
    103     private final static Comparator<Map<String, Object>> sDisplayNameComparator =
    104         new Comparator<Map<String, Object>>() {
    105         private final Collator   collator = Collator.getInstance();
    106 
    107         public int compare(Map<String, Object> map1, Map<String, Object> map2) {
    108             return collator.compare(map1.get("title"), map2.get("title"));
    109         }
    110     };
    111 
    112     //叶子列表项对应的Intent
    113     protected Intent activityIntent(String pkg, String componentName) {
    114         Intent result = new Intent();
    115         result.setClassName(pkg, componentName);
    116         return result;
    117     }
    118     
    119     //分类列表项对应的Intent
    120     protected Intent browseIntent(String path) {
    121         Intent result = new Intent();
    122         result.setClass(this, ApiDemos.class);
    123         result.putExtra("com.example.android.apis.Path", path);
    124         return result;
    125     }
    126 
    127     protected void addItem(List<Map<String, Object>> data, String name, Intent intent) {
    128         Map<String, Object> temp = new HashMap<String, Object>();
    129         temp.put("title", name);
    130         temp.put("intent", intent);
    131         data.add(temp);
    132     }
    133 
    134     @Override
    135     protected void onListItemClick(ListView l, View v, int position, long id) {
    136         Map<String, Object> map = (Map<String, Object>)l.getItemAtPosition(position);
    137 
    138         Intent intent = (Intent) map.get("intent");
    139         startActivity(intent);
    140     }
    141 }

     代码的103-109行自定义了一个比较器,用来对列表项进行排序。

    注意:

    ListActivity中的listView的每个Item都包含以下内容:

    1、  title,显示出来的内容;

    2、  intent,隐藏的内容,Intent类型主要有两种:

      一种指向叶子列表项,点击后运行具体的Activity;

      一种指向分类列表项,即点击后仍运行ApiDemos这个继承自ListActivity的Activity,只是此时该Activity对应的SimpleAdapter不一样了,因而类表显示的内容也不一样了。

    可以在eclipse中调试运行,这样可以更快的理解具体的流程:

    第一次获取数据源后(通过getData()获得),数据源的title项如下:

      Accessibility

      Animation

      App

      Content

      Graphics

      Media

      NFC

      OS

      Preference

      Text

      Views

    点击上面列出的项目后,如点击App后,将会启动App项隐藏的Intent 对应的Activity, 而该Activity仍为ApiDemos,所以进入之后就重新创建并初始化myData,其对应的内容为:

      ActionBar

      Activity

      Alarm

      …

    点击上面列出的项目后,如点击Activity后,将会启动Activity项隐藏的Intent对应的Activity,而该Activity仍为ApiDemos,所以进入之后重新创建并初始化myData,其对应的内容为:

      Animation

      Custom Dialog

      Custom Title

      …

    点击上面列出的项目后,如Custom Title后,将会启动Custom Title项隐藏的Intent对应的Activity,这是情况不一样了,此时的Activity对应的名称为ResolveInfo对象info中保存的名称为info.activityInfo.name的Activity,这是就可以看到效果!(此时就会呈现具体的界面)

    我们看到的列表显示效果都是按字典序排列的,这是因为在结尾调用了自定义的比较器sDisplayNameComparator的缘故!

    通过以上比较笨的步骤就能大致了解整个示例安排的结构了,噢耶!

  • 相关阅读:
    array note
    前端开发规范
    java集合分类
    react native环境
    gulp
    关于如何在海量手机号中刷选出想要的手机号
    生成用户头像插件
    下拉加载
    阿里云人脸人体识别调试心得与备忘
    Sublime text3使用时有卡顿现象
  • 原文地址:https://www.cnblogs.com/rainmonth/p/3599512.html
Copyright © 2011-2022 走看看