系统设计
        基于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界面如下:

使用ListActivity
        我们先来实现第一个用户界面: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实例开发之系统设计相关推荐

  1. RSS Reader实例开发之使用Service组件

    原文地址::http://www.ophonesdn.com/article/show/122 到目前为止,我们已经实现了RSS Reader的基本功能,在这个OPhone应用程序中,我们使用Acti ...

  2. RSS Reader实例开发之联网开发

    在OPhone应用程序中,如果我们要做一些费时的操作,例如,从网络获取数据,就不能将这些操作放在普通的处理UI的逻辑中,否则,主线程一旦执行耗时任务,将无法响应用户的任何操作,OPhone系统会判定该 ...

  3. Native Rss Reader 的资料

    转:http://hi.baidu.com/mikyliang/blog/item/11d420d3135832013af3cf19.html RSS文档的构成 2007-05-04 14:58 RS ...

  4. RSS Reader for MAC Code

    RSS Reader for MAC Code 该项目代码来自于王志刚 <软件创富密码:iPhone应用程序开发攻略之深入浅出Objective-C 2.0>一书,这是一个图例很丰富的书, ...

  5. 好用的RSS阅读器-My RSS Reader

    我对好用的RSS阅读器定义是 必须是免费的 必须可以自定义订阅源 必须是简洁的,不要华而不实 必须有夜间模式,毕竟保护眼睛是头等大事 基于以上几点,开发了 My RSS Reader . 目前已经发布 ...

  6. PhoneGap RSS Reader

    这是关于如何使用phoneGap来开发手机上的RSS阅读器的文章,原作者分别写了四个版本.如下所示: 原文链接:http://www.raymondcamden.com/index.cfm/2011/ ...

  7. wp实例开发精品文章源码推荐

    qianqianlianmeng wp实例开发精品文章源码推荐 WP8 启动媒体应用         这个示例演示了如何选择正确的msAudioCategory类别的音像(AV)流来配置它作为一个音频 ...

  8. 《ArcGIS Engine+C#实例开发教程》第三讲 MapControl与PageLayoutControl同步

    <ArcGIS Engine+C#实例开发教程>第三讲 MapControl与PageLayoutControl同步 原文:<ArcGIS Engine+C#实例开发教程>第三 ...

  9. WSE3.0构建Web服务安全(3):WSE3.0策略配置、证书、签名、与实例开发

    继WSE3.0构建Web服务安全(1):WSE3.0安全机制与实例开发和WSE3.0构建Web服务安全(2):非对称加密.公钥.密钥.证书.签名的区别和联系以及X.509 证书的获得和管理之后,今天我 ...

最新文章

  1. Spring Cloud微服务版本灰度发布新神器
  2. mysql性能优化的一些建议
  3. 怎样用Java自制优秀的图片验证码?这样!
  4. Git 实用技巧记录,看这篇你就明白了!
  5. 编写base64图片文件
  6. go 协程和协程通信
  7. 生活中有哪些越早明白越好的道理?
  8. 以太坊的4个发展阶段与难度炸弹
  9. [UnityShader基础]06.#pragma multi_compile
  10. CISSP考试过程,备考过程巨详细!
  11. Chrome 及驱动各版本下载地址
  12. 【AI视野·今日CV 计算机视觉论文速览 第186期】Fri, 6 Nov 2020
  13. 浅谈霍尔电流传感器的原理及应用
  14. word怎么设置边距为80磅_word 字体磅数 word怎么设置字体磅数
  15. 【SpringCloudAlibaba】微服务组件Dubbo
  16. 内地酒量排行榜山东居首 东北三省无一进前三
  17. Java学习之代码扫描工具的使用方法
  18. MySQL如何同时删除主外键关联的两张表中的数据
  19. USB转串口(rj45)使用secureCRT调试设备
  20. 基于微信小程序和安卓的婚恋相亲app

热门文章

  1. 我还是一个人.....
  2. android用户中心应用,腾讯应用中心触屏版上线 对Android开发者开放
  3. win8的计算机在哪个地方,Win8系统中的关机在电脑哪个位置
  4. 饺子播放器RecyclerView自动播放
  5. POI导入和导出Excel总结
  6. python编写自己的RBF径向基神经网络
  7. JS replace()方法
  8. 【Python 习题总结3】三种出路
  9. springboot在线竞拍平台java网上拍卖系统源码
  10. MVP in Android