我的淘宝店铺,http://shop61982302.taobao.com/,欢迎大家光临!你懂的,呵呵!先看这个rss阅读器,我将详细的开发过程,以及涉及到的很多基础知识介绍给大家
我的淘宝店铺,http://shop61982302.taobao.com/,欢迎大家光临!你懂的,呵呵!
在这个项目系列中,我将详细说明每个项目的开发过程,以及项目涉及到的很多基础知识。这些项目都是网上或者书本上的,由于这些项目开发过程讲的不是很详细,涉及到基层知识又特别多,自己阅读起来比较费劲。我将自己读懂的地方详细注释出来,希望大家可以快速读懂,快速应用到实际项目中,阅读时能起到事半功倍,举一反三效果!他山之石可以攻玉,呵呵!
第一个项目是RSS阅读器。运行效果如下图,显示的是我的博客的内容:
我的博客rss地址:http://www.cnblogs.com/flyone/rss,可以用google reader订阅
点击左边每一个条目都可以查看详细的内容,也就是跳转到第二个Activity,如下图
下面详细介绍开发过程,大家可以一步一步跟着我的截图来做:
1 新建一个工程:
2 在配置文件AndroidManifest.xml中,添加访问网络的权限,以及第二个activity信息,如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.fly.rss"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
//下面是访问网络的权限
<uses-permission android:name="android.permission.INTERNET" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".act_RssDemo"
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,显示博客详细内容
<activity android:name=".ActivityShowDescription"></activity>
</application>
</manifest>
3 设置主界面的布局文件Main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!-- <TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/> -->
<!-- ListView 以列表的形式展示具体内容,并且能够根据数据的长度自适应显示
在这篇文章的后面会详细附上ListView的用法 -->
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/itemlist"
/>
</LinearLayout>
4 设置第二个界面的布局文件showdescription.xml,利用向导创建即可:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:autoLink="all"
android:text=""
android:id="@+id/content"
android:layout_weight="1.0"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="返回"
android:id="@+id/back"
/>
</LinearLayout>
5 新建一个类保存xml文件中标签内容,也就是博客中的rss内容,即是一个Java bean
package com.fly.rss.data;
public class RSSItem
{
//xml文件中标签内容,变量要跟标签要对应起来
public static final String TITLE="title";
public static final String PUBDATE="pubdate";
private String title = null;
private String description = null;
private String link = null;
private String category = null;
private String pubdate = null;
public RSSItem()
{
}
public void setTitle(String title)
{
this.title = title;
}
public void setDescription(String description)
{
this.description = description;
}
public void setLink(String link)
{
this.link = link;
}
public void setCategory(String category)
{
this.category = category;
}
public void setPubDate(String pubdate)
{
this.pubdate = pubdate;
}
public String getTitle()
{
return title;
}
public String getDescription()
{
return description;
}
public String getLink()
{
return link;
}
public String getCategory()
{
return category;
}
public String getPubDate()
{
return pubdate;
}
public String toString()
{
if (title.length() > 20)
{
return title.substring(0, 42) + "...";
}
return title;
}
}
6 新建类将item内容插入到list中
package com.fly.rss.data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
public class RSSFeed
{
private String title = null;
private String pubdate = null;
private int itemcount = 0;
private List<RSSItem> itemlist;
public RSSFeed()
{
itemlist = new Vector(0);
}
public int addItem(RSSItem item)
{
itemlist.add(item);
itemcount++;
return itemcount;
}
public RSSItem getItem(int location)
{
return itemlist.get(location);
}
public List getAllItems()
{
return itemlist;
}
//将数据添加到list中以便于android控件listview建立关联
public List getAllItemsForListView(){
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
int size = itemlist.size();
for(int i=0;i<size;i++){
HashMap<String, Object> item = new HashMap<String, Object>();
item.put(RSSItem.TITLE, itemlist.get(i).getTitle());
item.put(RSSItem.PUBDATE, itemlist.get(i).getPubDate());
data.add(item);
}
return data;
}
int getItemCount()
{
return itemcount;
}
public void setTitle(String title)
{
this.title = title;
}
public void setPubDate(String pubdate)
{
this.pubdate = pubdate;
}
public String getTitle()
{
return title;
}
public String getPubDate()
{
return pubdate;
}
}
7 新建一个解析xml文件的类,注意这个是关键:
package com.fly.rss.data.sax;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
import com.fly.rss.data.*;
//
public class RSSHandler extends DefaultHandler
{
RSSFeed rssFeed;
RSSItem rssItem;
String lastElementName = "";
final int RSS_TITLE = 1;
final int RSS_LINK = 2;
final int RSS_DESCRIPTION = 3;
final int RSS_CATEGORY = 4;
final int RSS_PUBDATE = 5;
int currentstate = 0;
public RSSHandler()
{
}
//调用顺序跟代码位置无关
public RSSFeed getFeed()
{
return rssFeed;
}
//开始文档时调用
public void startDocument() throws SAXException
{
//实例化两个对象
rssFeed = new RSSFeed();
rssItem = new RSSItem();
}
public void endDocument() throws SAXException
{
}
public void startElement(String namespaceURI, String localName,String qName, Attributes atts) throws SAXException
{
if (localName.equals("channel"))
{
currentstate = 0;
return;
}
if (localName.equals("item"))
{
rssItem = new RSSItem();
return;
}
if (localName.equals("title"))
{
currentstate = RSS_TITLE;
return;
}
if (localName.equals("description"))
{
currentstate = RSS_DESCRIPTION;
return;
}
if (localName.equals("link"))
{
currentstate = RSS_LINK;
return;
}
if (localName.equals("category"))
{
currentstate = RSS_CATEGORY;
return;
}
if (localName.equals("pubDate"))
{
currentstate = RSS_PUBDATE;
return;
}
currentstate = 0;
}
public void endElement(String namespaceURI, String localName, String qName) throws SAXException
{
//如果解析一个item节点结束,就将rssItem添加到rssFeed中。
if (localName.equals("item"))
{
rssFeed.addItem(rssItem);
return;
}
}
public void characters(char ch[], int start, int length)
{
String theString = new String(ch,start,length);
switch (currentstate)
{
case RSS_TITLE:
rssItem.setTitle(theString);
currentstate = 0;
break;
case RSS_LINK:
rssItem.setLink(theString);
currentstate = 0;
break;
case RSS_DESCRIPTION:
rssItem.setDescription(theString);
currentstate = 0;
break;
case RSS_CATEGORY:
rssItem.setCategory(theString);
currentstate = 0;
break;
case RSS_PUBDATE:
rssItem.setPubDate(theString);
currentstate = 0;
break;
default:
return;
}
}
}
8 主界面Activity代码acc_RssDemo.java
package com.fly.rss;
import java.net.URL;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.AdapterView.OnItemClickListener;
import com.fly.rss.data.*;
import com.fly.rss.data.sax.*;
public class act_RssDemo extends Activity implements OnItemClickListener
{
//我的博客的rss地址
public final String RSS_URL = "http://www.cnblogs.com/flyone/rss";
public final String tag = "RSSReader";
private RSSFeed feed = null;
/** Called when the activity is first created. */
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
feed = getFeed(RSS_URL);
showListView();
}
//得到rss地址中xml文件的内容进行解析
private RSSFeed getFeed(String urlString)
{
try
{
URL url = new URL(urlString);
//新建一个工厂类
SAXParserFactory factory = SAXParserFactory.newInstance();
//工厂类产生出一个sax的解析类
SAXParser parser = factory.newSAXParser();
XMLReader xmlreader = parser.getXMLReader();
RSSHandler rssHandler = new RSSHandler();
xmlreader.setContentHandler(rssHandler);
InputSource is = new InputSource(url.openStream());
xmlreader.parse(is);
//调用解析的类
return rssHandler.getFeed();
}
catch (Exception ee)
{
return null;
}
}
//将解析的xml文件展示出来
private void showListView()
{
ListView itemlist = (ListView) findViewById(R.id.itemlist);
if (feed == null)
{
setTitle("访问的RSS无效");
return;
}
SimpleAdapter adapter = new SimpleAdapter(this, feed.getAllItemsForListView(),
android.R.layout.simple_list_item_2, new String[] { RSSItem.TITLE,RSSItem.PUBDATE },
new int[] { android.R.id.text1 , android.R.id.text2});
itemlist.setAdapter(adapter);
itemlist.setOnItemClickListener(this);
itemlist.setSelection(0);
}
//单击listView时跳转到第二个Activity
public void onItemClick(AdapterView parent, View v, int position, long id)
{
Intent itemintent = new Intent(this,ActivityShowDescription.class);
Bundle b = new Bundle();
b.putString("title", feed.getItem(position).getTitle());
b.putString("description", feed.getItem(position).getDescription());
b.putString("link", feed.getItem(position).getLink());
b.putString("pubdate", feed.getItem(position).getPubDate());
itemintent.putExtra("android.intent.extra.rssItem", b);
startActivityForResult(itemintent, 0);
}
}
9 第二个activity代码 ActivityShowDescription
package com.fly.rss;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.content.Intent;
import android.view.*;
public class ActivityShowDescription extends Activity {
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.showdescription);
String content = null;
Intent startingIntent = getIntent();
if (startingIntent != null) {
Bundle bundle = startingIntent
.getBundleExtra("android.intent.extra.rssItem");
if (bundle == null) {
content = "不好意思程序出错啦";
} else {
/* content = bundle.getString("title") + "\n\n"
+ bundle.getString("pubdate") + "\n\n"
+ bundle.getString("description").replace('\n', ' ')
+ "\n\n详细信息请访问以下网址:\n" + bundle.getString("link");*/
content = bundle.getString("title") + "\n\n"
+ bundle.getString("pubdate") + "\n\n";
//+ bundle.getString("pubdate") + "\n\n"
//+ "\n\n详细信息请访问以下网址:\n" + bundle.getString("link");
}
} else {
content = "不好意思程序出错啦";
}
TextView textView = (TextView) findViewById(R.id.content);
textView.setText(content);
Button backbutton = (Button) findViewById(R.id.back);
backbutton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
finish();
}
});
}
}
至此rss阅读器涉及到主要代码就全部完成了,大家可以点击运行了!
上面的简单例子涉及到的知识点有:
当然还有很多,大家不懂时可以继续google!