Android项目之 RSS阅读器(1)

来源:转载

   我的淘宝店铺,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.javapackage 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代码 ActivityShowDescriptionpackage 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阅读器涉及到主要代码就全部完成了,大家可以点击运行了!上面的简单例子涉及到的知识点有:(1)ListView,详细的介绍:http://www.cnblogs.com/allin/archive/2010/05/11/1732200.html(2)sax解析xml文件,详细的介绍:http://blog.csdn.net/shimiso/article/details/5493125(3)ArrayAdapter的用法,详细的介绍:http://apps.hi.baidu.com/share/detail/30784807当然还有很多,大家不懂时可以继续google!

分享给朋友:
您可能感兴趣的文章:
随机阅读: