RSS Reader实例开发之系统设计
系统设计
基于OPhone的RSS Reader将以Google Reader的功能为参考,并充分考虑到手机屏幕的限制。RSS Reader将实现以下几个Activity:
1. MainActivity:负责列出当前订阅的所有Item,根据用户设置显示未读项或全部项;
2. ReadActivity:当用户点击MainActivity的某一个Item时,显示Item的详细内容;
3. SubsActivity:负责列出当前的所有订阅,并可以添加或删除;
4. PrefActivity:显示选项设置,可以修改或取消。
Activity的切换是根据用户点击或选择菜单时发起的。在编写代码之前,我们先绘制这4个Activity的草图。祭出UI设计的利器——Microsoft Excel!没错,利用Excel强大的表格编辑功能,我们能很容易地作出UI界面。设计的4个Activity界面如下:
我们先来实现第一个用户界面:MainActivity。它用于显示当前所有的Item,显然,ListView符合我们的要求。当我们需要一个充满整个屏幕的ListView时,使用ListActivity更加简单,因为ListActivity已经封装了对ListView的操作,我们可以通过ListActivity直接显示Item列表。
新建OPhone工程,命名为RssReader,然后,修改SDK自动为我们生成的MainActivity,将继承关系由Activity改为ListActivity:
01.package org.expressme.wireless.reader; 02. 03.public class MainActivity extends ListActivity { 04. 05. @Override 06. public void onCreate(Bundle savedInstanceState) { 07. super.onCreate(savedInstanceState); 08. setContentView(R.layout.main); 09. setTitle(getResources().getString(R.string.app_name)); 10. } 11.}
有一个id为list的ListView,这样,ListActivity才能正确关联该ListView,因此,我们修改res/layout/main.xml,放入一个id为list的ListView:
01.<?xml version="1.0" encoding="utf-8"?> 02.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 03. android:orientation="vertical" 04. android:layout_width="fill_parent" 05. android:layout_height="fill_parent" 06.> 07. <ListView 08. android:id="@android:id/list" 09. android:layout_width="fill_parent" 10. android:layout_height="fill_parent" 11. android:layout_weight="1" 12. android:drawSelectorOnTop="false" 13. /> 14. <TextView 15. android:id="@android:id/empty" 16. android:layout_width="fill_parent" 17. android:layout_height="fill_parent" 18. android:text="No data display" 19. /> 20.</LinearLayout>
ListActivity要求被显示的View中必须最外层的LinearLayout是最常用的线性布局,指定其layout_width和layout_height属性均为fill_parent,表示充满整个屏幕,该LinearLayout包含一个id为list的ListView和一个id为empty的TextView。当ListView中没有可以显示的列表项时,这个TextView将自动显示,会提示用户“No data display”,当ListView中至少有一个列表项时,这个TextView将自动隐藏。这些功能都是ListActivity为我们自动实现的,无需再手动编写逻辑。
运行RssReader,屏幕显示“No data display”,因为我们还没有向ListView中添加任何列表项。
下面,我们将向ListView中添加一些列表项。在OPhone系统中,如果要在UI中显示数据,需要使用Adapter来绑定数据,这样可以将UI的显示逻辑和具体的数据分离。例如,ListView需要一个数组来表示列表项,就可以使用最常用的ArrayAdapter,将任意数组绑定到ListView中。为了让ListView显示一个字符串数组表示的列表项,我们只需要在onCreate()方法中添加一句:
01.setListAdapter( 02. new ArrayAdapter<String>( 03. this, 04. android.R.layout.simple_list_item_1, 05. new String[] { 06. "谷歌推出新的编程语言- Go", 07. "苹果发布Safari 4.0.4", 08. "Apache计划年底发布Tomcat 7测试版", 09. "微软结伴Eclipse共同推进Azure开发", 10. "苹果设计史上16个梦幻产品设计", 11. "Ubuntu 9.10 正式发布", 12. "HTC Hero可升级至Android 2.0" 13. } 14. ) 15.);
自带的android.R.layout.simple_list_item_1。通过查看源码可以看到,simple_list_item_1非常简单,仅包含一个TextView,用于显示单行文字:
01.<?xml version="1.0" encoding="utf-8"?> 02.<TextView xmlns:android="http://schemas.android.com/apk/res/android" 03. android:id="@android:id/text1" 04. android:layout_width="fill_parent" 05. android:layout_height="wrap_content" 06. android:textAppearance="?android:attr/textAppearanceLarge" 07. android:gravity="center_vertical" 08. android:paddingLeft="6dip" 09. android:minHeight="?android:attr/listPreferredItemHeight" 10./>
ArrayAdapter需要一个int参数指定用于显示每个列表项的layout的id,由于OPhone系统本身已经内置了一些常用的layout,对于ListView的列表项使用的layout,可以直接指定OPhone我们可以在此基础上修改,以便实现定制外观的列表项。运行应用程序,列表项显示效果如下:
小提示:当使用非String泛型的ArrayAdapter时,例如自定义的JavaBean,ArrayAdapter会自动调用toString()方法,所以,确保正确覆写了toString()方法,就能正确显示列表项。
当用户点击某一个列表项时,可以通过向ListView注册OnItemClickListener来接收事件。由于我们使用的ListActivity已经自动向其包含的ListView注册了OnItemClickListener,我们只需要覆写ListActivity的onListItemClick()方法即可。
现在,我们已经用硬编码的方式显示出了RSS的Item项。如果我们把硬编码的数组替换成从网络读取的RSS列表项,就可以完成一个最基本的RSS Reader了。
深入ListView
趁着对ListActivity的熟悉,我们继续编写管理订阅的SubsActivity。SubsActivity需要列出所有的订阅,自然是继承ListActivity比较方便了。此外,删除菜单需要用户选择一个订阅,然后才能删除选中的订阅,因此,和MainActivity对ListView的布局和操作又有所不同。
我们先根据MainActivity写出SubsActivity的框架:
01.package org.expressme.wireless.reader; 02. 03.public class SubsActivity extends ListActivity { 04. public void onCreate(Bundle savedInstanceState) { 05. super.onCreate(savedInstanceState); 06. setContentView(R.layout.subs); 07. setTitle("Manage Subscriptions"); 08. setListAdapter(new ArrayAdapter<String>( 09. this, 10. android.R.layout.simple_list_item_single_choice, 11. new String[] { 12. "廖雪峰的官方网站", 13. "李开复的博客", 14. "Google 黑板报", 15. "郎咸平官方博客" 16. } 17. )); 18. } 19.}
注意到ListView的列表项使用的layout是android.R.layout.simple_list_item_single_choice,该Layout包含一个CheckedTextView,可以显示一个单选按钮和一个字符串。仿照MainActivity的布局,编写subs.xml:
01.<?xml version="1.0" encoding="utf-8"?> 02.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 03. android:orientation="vertical" 04. android:layout_width="fill_parent" 05. android:layout_height="fill_parent" 06. android:paddingLeft="6dip" 07. android:paddingRight="6dip" 08.> 09. <ListView 10. android:id="@android:id/list" 11. android:layout_width="fill_parent" 12. android:layout_height="fill_parent" 13. android:layout_weight="1" 14. android:drawSelectorOnTop="false" 15. android:choiceMode="singleChoice" 16. /> 17. <TextView 18. android:id="@android:id/empty" 19. android:layout_width="fill_parent" 20. android:layout_height="fill_parent" 21. android:text="No subscription" 22. /> 23.</LinearLayout>
不要忘了向AndroidManifest.xml文件中添加SubsActivity的声明。SubsActivity运行结果如下:
点击列表项,发现单选按钮并未选中,因为ListActivity还没有为我们把单选逻辑封装进去,所以,需要再添加一点代码。首先,为SubsActivity添加一个成员变量,记录当前选中的列表项的索引:
private int selected = (-1); // (-1)表示未选中任何项
然后,覆写onListItemClick()方法:
01.@Override 02.protected void onListItemClick(ListView l, View v, int position, long id) { 03. if (this.selected!=(-1)) { 04. View last = this.getListView().getChildAt(selected); 05. ((CheckedTextView) last).setChecked(false); 06. } 07. this.selected = position; 08. ((CheckedTextView) v).setChecked(true); 09.}
因为我们为ArrayAdapter指定了一个包含CheckedTextView的layout,因此,在onListItemClick()方法中传入的View参数就是一个CheckedTextView,将其强制转型,并设置其checked状态就可以了。
现在,点击某个列表项,其对应的单选按钮就被选中了:
不过,当用户在带有摇杆的真实手机上操作时,直接点击触摸屏是可以选中单选按钮的,使用摇杆上下选择时则不行(测试时可以用鼠标滚轮模拟),因为我们还没有编写代码响应ListView的OnItemSelected事件。在onCreate()方法中追加代码如下:
01.getListView().setOnItemSelectedListener(new OnItemSelectedListener() { 02. public void onItemSelected(AdapterView<?> parent, View v, int position, long id) { 03. if (selected!=(-1)) { 04. View last = getListView().getChildAt(selected); 05. ((CheckedTextView) last).setChecked(false); 06. } 07. selected = position; 08. ((CheckedTextView) v).setChecked(true); 09. } 10. public void onNothingSelected(AdapterView<?> parent) { 11. } 12.});
现在,通过鼠标滚轮模拟手机摇杆操作,单选框会自动被选中:
使用Intent
现在,我们已经编写了两个Activity:MainActivity和SubsActivity。当用户启动RSS Reader时,显示MainActivity,当用户希望管理订阅时,我们如何从MainActivity中启动SubsActivity呢?在OPhone系统中,各种组件不是直接调用,而是通过Intent联系起来的。例如,MainActivity想要启动SubsActivity,就可以实例化一个Intent,然后通过startActivity()方法告诉OPhone系统执行这个Intent就可以了:
01.Intent intent = new Intent(this, SubsActivity.class); 02.startActivity(intent);
通过指定Activity的class来启动Intent称之为显式启动一个Intent,此外,在OPhone系统中还可以隐式地启动一个Intent。什么时候我们需要一个隐式的Intent呢?例如,应用程序需要调用OPhone系统的浏览器为用户显示一个URL时,应用程序很难知道浏览器的Activity的类名(事实上,从应用程序之间的耦合关系上讲,最好不要知道浏览器的Activity的任何信息),这时,通过构造一个隐式的Intent,让OPhone系统自己去寻找合适的浏览器为用户打开这个URL:
01.Intent intent = new Intent( 02. Intent.ACTION_VIEW, 03. Uri.parse("http://www.liaoxuefeng.com/")); 04.startActivity(intent);
除了调用系统浏览器外,拨打电话、发送短信等系统操作都可以通过隐式的Intent实现,OPhone系统的这种设计可以让不同的应用程序通过Mashup的方式组合,而用户几乎感觉不到在不同的应用程序间切换。
RSS Reader实例开发之系统设计相关推荐
- RSS Reader实例开发之使用Service组件
原文地址::http://www.ophonesdn.com/article/show/122 到目前为止,我们已经实现了RSS Reader的基本功能,在这个OPhone应用程序中,我们使用Acti ...
- RSS Reader实例开发之联网开发
在OPhone应用程序中,如果我们要做一些费时的操作,例如,从网络获取数据,就不能将这些操作放在普通的处理UI的逻辑中,否则,主线程一旦执行耗时任务,将无法响应用户的任何操作,OPhone系统会判定该 ...
- Native Rss Reader 的资料
转:http://hi.baidu.com/mikyliang/blog/item/11d420d3135832013af3cf19.html RSS文档的构成 2007-05-04 14:58 RS ...
- RSS Reader for MAC Code
RSS Reader for MAC Code 该项目代码来自于王志刚 <软件创富密码:iPhone应用程序开发攻略之深入浅出Objective-C 2.0>一书,这是一个图例很丰富的书, ...
- 好用的RSS阅读器-My RSS Reader
我对好用的RSS阅读器定义是 必须是免费的 必须可以自定义订阅源 必须是简洁的,不要华而不实 必须有夜间模式,毕竟保护眼睛是头等大事 基于以上几点,开发了 My RSS Reader . 目前已经发布 ...
- PhoneGap RSS Reader
这是关于如何使用phoneGap来开发手机上的RSS阅读器的文章,原作者分别写了四个版本.如下所示: 原文链接:http://www.raymondcamden.com/index.cfm/2011/ ...
- wp实例开发精品文章源码推荐
qianqianlianmeng wp实例开发精品文章源码推荐 WP8 启动媒体应用 这个示例演示了如何选择正确的msAudioCategory类别的音像(AV)流来配置它作为一个音频 ...
- 《ArcGIS Engine+C#实例开发教程》第三讲 MapControl与PageLayoutControl同步
<ArcGIS Engine+C#实例开发教程>第三讲 MapControl与PageLayoutControl同步 原文:<ArcGIS Engine+C#实例开发教程>第三 ...
- WSE3.0构建Web服务安全(3):WSE3.0策略配置、证书、签名、与实例开发
继WSE3.0构建Web服务安全(1):WSE3.0安全机制与实例开发和WSE3.0构建Web服务安全(2):非对称加密.公钥.密钥.证书.签名的区别和联系以及X.509 证书的获得和管理之后,今天我 ...
最新文章
- Spring Cloud微服务版本灰度发布新神器
- mysql性能优化的一些建议
- 怎样用Java自制优秀的图片验证码?这样!
- Git 实用技巧记录,看这篇你就明白了!
- 编写base64图片文件
- go 协程和协程通信
- 生活中有哪些越早明白越好的道理?
- 以太坊的4个发展阶段与难度炸弹
- [UnityShader基础]06.#pragma multi_compile
- CISSP考试过程,备考过程巨详细!
- Chrome 及驱动各版本下载地址
- 【AI视野·今日CV 计算机视觉论文速览 第186期】Fri, 6 Nov 2020
- 浅谈霍尔电流传感器的原理及应用
- word怎么设置边距为80磅_word 字体磅数 word怎么设置字体磅数
- 【SpringCloudAlibaba】微服务组件Dubbo
- 内地酒量排行榜山东居首 东北三省无一进前三
- Java学习之代码扫描工具的使用方法
- MySQL如何同时删除主外键关联的两张表中的数据
- USB转串口(rj45)使用secureCRT调试设备
- 基于微信小程序和安卓的婚恋相亲app