android ApiDemos学习1 主界面动态ListView显示
0 Android提供了一个供开发者学习使用的示例程序。其界面如下。图中可以看到,应用列表应为ListView,看其源码发现,并非为简单的ListView,而是采用动态加载的方式。
1 主界面代码如下:
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 @Override139 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 }
下面为部分配置文件代码:
<?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节点的所有信息,稍后可以根据这些信息对其进行加载。
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); 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显示相关推荐
- Android 悬浮窗在主界面点击显示悬浮窗界面后,再通过后台,调起app,界面依然是悬浮窗的界面,解决思路
通过监听悬浮窗的按键事件,如果不是悬浮窗的按键的事件,就直接跳到mainActivity中,
- aswing学习笔记4-通过调用面板中的按钮实现主界面动态切换皮肤的问题!
通过调用面板中的按钮实现主界面动态切换皮肤的问题! 发表于 : 周三 10月 29, 2008 2:09 pm 由 xueyuan cyz 现在我在做一个动态切换皮肤的的功能,原理是通过点击 调用面板 ...
- 泰斗破环神学习笔记——主界面开发
泰斗破环神学习笔记--主界面开发 主界面主要就是,角色状态面板.角色信息面板.金币与钻石数额面板 文章目录 泰斗破环神学习笔记--主界面开发 前言 一.委托(delegate) 二.事件(Event) ...
- Android项目Tab类型主界面大总结 Fragment+TabPageIndicator+ViewPager
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24740977 Android如今实现Tab类型的界面方式越来越多,今天就把常见的 ...
- 如何让fragment刷新界面_快速实现android版抖音主界面的心得
原文作者:DK_BurNIng 如何快速确定竞品某个界面的实现方式? 当你收到产品一个需求是模仿某个竞品且时间很短没有过多时间给你调研技术方案的时候,如何尽快确定这个功能的技术方案呢? 这里我给出我自 ...
- Android开发学习之快速实现圆角ListView
一如既往,我们继续从微信当中寻找Android开发的思路,我们一起来看下面的这样一个效果. 这是微信里的一个界面,可以看到的是这个界面中大量使用了圆角的元素.当然,在其他的应用中,我们依然可以找到类似 ...
- android 开发性格测试软件,性格色彩测试android程序开发之一--主界面
思路:主界面只有一张背景图片,两个按钮,当按钮按下的时候,按钮的颜色会发生相应的变化,按下的分成了三个状态,default,pressed和selected. 在Activity中,对button进行 ...
- 云炬Android开发笔记 9主界面-通用底部导航设计与一键式封装
阅读目录 1.底部导航BottomBar设计与实现 1.1 说明 1.2 基于每个tab的子frament的父类的实现 1.3 建立bean类包含tab的信息(icon+文字) 2.打造适合电商主界 ...
- Android实战简单新闻主界面设计
前言 这是自己学习过程单独做出来的,挺适合新手学习,熟悉最基本的banner,imageview,listview,text等等基础控件,适合初学者,原项目共有五个模块,这个是其中一个模块 提示:以下 ...
最新文章
- 一文搞懂 CountDownLatch 用法和源码!
- 感恩节里我成了一个不解风情的爸爸
- [IE9] 如何让你的网站在IE9和Win7任务栏上更闪亮
- QT5对话框的中文字符串【乱码】 (error: C2001: 常量中有换行符)
- CentOS 6.6编译安装LAMP(Apache2+PHP+Mysql+PHPmyAdmin)
- 过滤选择器——子元素过滤选择器
- excelutil java_JAVA实现Excel的读取--ExcelUtil工具类
- MapReduce 2 中一些基础数据类型
- 【C++ grammar】抽象、封装与this指针
- React-Native 之 GD (十三)数据持久化(realm) 及 公共Cell
- 基于Jenkins 快速搭建持续集成环境
- 雷电三接口有什么用_「滕·Gallery」我是如何用奥睿科雷电三硬盘盒来弥补之前的失误的? | 数字尾巴 分享美好数字生活...
- django mac 安装mysql_mac安装MySQL-Python报错
- Android无线安全测试工具-WiFinSpect
- Java学习之InputStream中read()与read(byte[] b)
- asp.net中commandname应用
- 单片机入门到高级开挂学习路径(附教程+工具)
- iPad Pro机身无故弯曲 Apple对此做出回应及应对
- numeric_limits 解析
- html5怎么有漂浮的效果,实现元素漂浮在水面特效的jQuery插件