Android新闻客户端(仿网易)--下
一、摘要继上一篇博客《模仿网易新闻客户端(上)》之后,笔者继续开发我们自己的“网易新闻客户端”,由于找不到现成的url新闻链接地址,所以这里就用RSS订阅所提供的url,这里所用到的链接仍然是网易新闻中心的RSS地址http://www.163.com/rss/,然后通过解析xml内容,以ListView的方式呈现在手机界面上。还有一个问题,因为RSS所提供的xml资源里面,没有对应item的图片,所以,ListView里面每一个Item都没有图片,这点有点遗憾,但也没事,实现其功能就行了。废话不多说,老惯例,先看效果图
三、解析RSS
首先,先大概地看一下RSS所提供XML的数据结构,下面是一个RSS文件结构示例
<?xml version="1.0" encoding="GBK"?>??<?xml-stylesheet type="text/css" ?>??<rss version="2.0">??<channel>??<title>网易头条新闻</title>??<link><a href=""http://news.163.com/</link"" target=""_blank"">http://news.163.com/</link></a>??<description>网易头条新闻</description>??<pubDate>Mon, 2 Apr 2012 01:07:10 GMT</pubDate>??<lastBuildDate>Mon, 2 Apr 2012 01:07:10 GMT</lastBuildDate>??<item id="1">??<title>...</title>??<link><a href=""http://news.163.com/12/0402/08/7U2TBKQF0001124J.html</link"" target=""_blank"">http://news.163.com/12/0402/08/7U2TBKQF0001124J.html</link></a>??<description>......</description>??<pubDate>2012-04-02 09:07:10</pubDate>??</item>??</channel>??</rss>
package com.and.netease.rss;?public class RSSItem {???? private String title;??? private String link;??? private String description;??? private String pubDate;???? public RSSItem() {???? ???super();??? }???? public String getTitle() {???? ???return title;??? }???? public void setTitle(String title) {???? ???this.title = title;??? }???? public String getLink() {???? ???return link;??? }???? public void setLink(String link) {???? ???this.link = link;??? }???? public String getDescription() {???? ???return description;??? }???? public void setDescription(String description) {???? ???this.description = description;??? }???? public String getPubDate() {???? ???return pubDate;??? }???? public void setPubDate(String pubDate) {???? ???this.pubDate = pubDate;??? }???? @Override??? public String toString() {???? ???return "RSSItem [title=" + title + ", link=" + link + ", description="???? ?? ?? ?? ? + description + ", pubDate=" + pubDate + "]";??? }?}
package com.and.netease.rss;?import java.util.ArrayList;import java.util.List;?import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;?import android.text.Html;?public class RSSHandler extends DefaultHandler {???? private List<RSSItem> list;??? private RSSItem item;??? private String tag = "";??? ???? private StringBuffer buffer;??? @Override??? public void characters(char[] ch, int start, int length)???? ?? ?? ?throws SAXException {???? ???super.characters(ch, start, length);???? ???if(item!=null){???? ?? ?? ?String data = new String(ch,start,length);???? ?? ?? ?if(tag.equals("title")){???? ?? ?? ?? ? item.setTitle(data);???? ?? ?? ?}else if(tag.equals("link")){???? ?? ?? ?? ? item.setLink(data);???? ?? ?? ?}else if(tag.equals("description")){//? ?? ?? ?? ?? ? item.setDescription(data);???? ?? ?? ?? ? buffer.append(Html.fromHtml(data));???? ?? ?? ?}else if(tag.equals("pubDate")){???? ?? ?? ?? ? item.setPubDate(data);???? ?? ?? ?}???? ???}??? }???? @Override??? public void endDocument() throws SAXException {???? ???super.endDocument();??? }???? @Override??? public void endElement(String uri, String localName, String qName)???? ?? ?? ?throws SAXException {???? ???super.endElement(uri, localName, qName);???? ???if(localName.equals("item")){???? ?? ?? ?item.setDescription(buffer.toString());???? ?? ?? ?list.add(item);???? ?? ?? ?item = null;???? ?? ?? ?buffer = null;???? ???}???? ???tag = "";??? }???? @Override??? public void startDocument() throws SAXException {???? ???super.startDocument();???? ???list = new ArrayList<RSSItem>();??? }???? @Override??? public void startElement(String uri, String localName, String qName,???? ?? ?? ?Attributes attributes) throws SAXException {???? ???super.startElement(uri, localName, qName, attributes);???? ???if(localName.equals("item")){???? ?? ?? ?item = new RSSItem();???? ?? ?? ?buffer = new StringBuffer();???? ???}???? ???tag = localName;??? }??? ???? public List<RSSItem> getData(){???? ???return list;??? }?}
View Code ?package com.and.netease;?public class CONST {???? public static final String URL_NEWS_TOP = "http://news.163.com/special/00011K6L/rss_newstop.xml";??? public static final String URL_NEWS_SPORT = "http://sports.163.com/special/00051K7F/rss_sportslq.xml";??? public static final String URL_NEWS_PLAY = "http://ent.163.com/special/00031K7Q/rss_toutiao.xml";??? public static final String URL_NEWS_FINANCE = "http://money.163.com/special/00252EQ2/yaowenrss.xml";??? public static final String URL_NEWS_SCIENCE = "http://tech.163.com/special/000944OI/headlines.xml";???? //国内??? public static final String URL_NEWS_DOMESTIC = "http://news.163.com/special/00011K6L/rss_gn.xml";??? //军事??? public static final String URL_NEWS_MILITARY = "http://news.163.com/special/00011K6L/rss_war.xml";??? //国际??? public static final String URL_NEWS_INTERNATIONAL = "http://news.163.com/special/00011K6L/rss_gj.xml";??? //社会??? public static final String URL_NEWS_COMMUNITY = "http://news.163.com/special/00011K6L/rss_sh.xml";??? //深度??? public static final String URL_NEWS_DEPTH = "http://news.163.com/special/00011K6L/rss_hotnews.xml";??? //彩票??? public static final String URL_NEWS_TICKET = "http://sports.163.com/special/00051K7F/rss_sportscp.xml";??? //电影??? public static final String URL_NEWS_FILM = "http://ent.163.com/special/00031K7Q/rss_entmovie.xml";??? //音乐??? public static final String URL_NEWS_MUSIC = "http://ent.163.com/special/00031K7Q/rss_entmusic.xml";??? //IT??? public static final String URL_NEWS_IT = "http://tech.163.com/special/000944OI/kejiyejie.xml";??? //汽车??? public static final String URL_NEWS_CAR = "http://auto.163.com/special/00081K7D/rsstoutiao.xml";??? //数码??? public static final String URL_NEWS_DIGITAL = "http://tech.163.com/digi/special/00161K7K/rss_digixj.xml";??? ???? ???? //网易话题??? public static final String URL_TOPIC = "http://news.163.com/special/00011K6L/rss_newsspecial.xml";??? //网易图片??? public static final String URL_PICTURE = "http://news.163.com/special/00011K6L/rss_photo.xml";??? //网易跟帖??? public static final String URL_FOLLOW = "";??? //网易投票??? public static final String URL_VOTE = "";??? ?}
intent = new Intent(TabNewsActivity.this, TabNewsTopActivity.class);? ?? ???page = getLocalActivityManager().startActivity("activity1", intent).getDecorView();? ?? ???LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);? ?? ???layout_news_main.addView(page, params);
viewSwitcher = (ViewSwitcher) findViewById(R.id.viewswitcher_news_top);? ?? ???listView = new MyListView(this);? ?? ???...? ?? ???viewSwitcher.addView(listView);? ?? ???viewSwitcher.addView(getLayoutInflater().inflate(R.layout.layout_progress_page, null));? ?? ???viewSwitcher.showNext();
package com.and.netease;?import java.io.InputStream;import java.io.InputStreamReader;import java.io.Reader;import java.net.URL;import java.net.URLConnection;import java.nio.charset.Charset;import java.util.List;?import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;?import org.xml.sax.InputSource;import org.xml.sax.XMLReader;?import com.and.netease.MyListView.OnRefreshListener;import com.and.netease.rss.RSSHandler;import com.and.netease.rss.RSSItem;?import android.app.Activity;import android.content.Intent;import android.graphics.Color;import android.os.AsyncTask;import android.os.Bundle;import android.os.Handler;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;import android.widget.ViewSwitcher;?public class TabNewsTopActivity extends Activity {???? MyListView listView;???? List<RSSItem> list;??? RSSHandler rssHandler;???? MyAdapter adapter;???? ViewSwitcher viewSwitcher;???? @Override??? protected void onCreate(Bundle savedInstanceState) {???? ???super.onCreate(savedInstanceState);???? ???setContentView(R.layout.layout_news_top);???? ???setTheme(android.R.style.Theme_Translucent_NoTitleBar);????? ???initViews();????? ???rssHandler = new RSSHandler();???? ???requestRSSFeed();???? }???? private void initViews() {???? ???viewSwitcher = (ViewSwitcher) findViewById(R.id.viewswitcher_news_top);???? ???listView = new MyListView(this);???? ???listView.setCacheColorHint(Color.argb(0, 0, 0, 0));???? ???ImageView testView = new ImageView(this);???? ???testView.setImageResource(R.drawable.temp);???? ???listView.addHeaderView(testView);???? ???listView.setonRefreshListener(refreshListener);???? ???????? ???viewSwitcher.addView(listView);???? ???viewSwitcher.addView(getLayoutInflater().inflate(R.layout.layout_progress_page, null));???? ???viewSwitcher.showNext();???? ???listView.setOnItemClickListener(listener);???? }??? ???? private OnRefreshListener refreshListener = new OnRefreshListener() {???? ???????? ???@Override???? ???public void onRefresh() {???? ?? ?? ?// TODO Auto-generated method stub???? ?? ?? ?new AsyncTask<Void, Void, Void>() {???? ?? ?? ?? ? protected Void doInBackground(Void... params) {???? ?? ?? ?? ?? ???try {???? ?? ?? ?? ?? ?? ?? ?Thread.sleep(1000);???? ?? ?? ?? ?? ???} catch (Exception e) {???? ?? ?? ?? ?? ?? ?? ?e.printStackTrace();???? ?? ?? ?? ?? ???}???? ?? ?? ?? ?? ???????? ?? ?? ?? ?? ???return null;???? ?? ?? ?? ? }????? ?? ?? ?? ? @Override???? ?? ?? ?? ? protected void onPostExecute(Void result) {???? ?? ?? ?? ?? ???adapter.notifyDataSetChanged();???? ?? ?? ?? ?? ???listView.onRefreshComplete();???? ?? ?? ?? ? }????? ?? ?? ?}.execute(null);???? ???}??? };???? private void requestRSSFeed() {???? ???Thread t = new Thread() {???? ?? ?? ?@Override???? ?? ?? ?public void run() {???? ?? ?? ?? ? super.run();???? ?? ?? ?? ? try {???? ?? ?? ?? ?? ???URL url = new URL(CONST.URL_NEWS_TOP);???? ?? ?? ?? ?? ???URLConnection con = url.openConnection();???? ?? ?? ?? ?? ???con.connect();????? ?? ?? ?? ?? ???InputStream input = con.getInputStream();????? ?? ?? ?? ?? ???SAXParserFactory fac = SAXParserFactory.newInstance();???? ?? ?? ?? ?? ???SAXParser parser = fac.newSAXParser();???? ?? ?? ?? ?? ???XMLReader reader = parser.getXMLReader();???? ?? ?? ?? ?? ???reader.setContentHandler(rssHandler);???? ?? ?? ?? ?? ???Reader r = new InputStreamReader(input, Charset.forName("GBK"));???? ?? ?? ?? ?? ???reader.parse(new InputSource(r));???? ?? ?? ?? ?? ???list = rssHandler.getData();//? ?? ?? ?? ?? ?? ???for (RSSItem rss : list) {//? ?? ?? ?? ?? ?? ?? ?? ?System.out.println(rss);//? ?? ?? ?? ?? ?? ???}???? ?? ?? ?? ?? ???if (list.size() == 0) {???? ?? ?? ?? ?? ?? ?? ?handler.sendEmptyMessage(-1);???? ?? ?? ?? ?? ???} else {???? ?? ?? ?? ?? ?? ?? ?handler.sendEmptyMessage(1);???? ?? ?? ?? ?? ???}???? ?? ?? ?? ? } catch (Exception e) {???? ?? ?? ?? ?? ???e.printStackTrace();???? ?? ?? ?? ? }???? ?? ?? ?}???? ???};???? ???t.start();??? }???? Handler handler = new Handler() {???? ???public void handleMessage(android.os.Message msg) {???? ?? ?? ?if (msg.what == 1) {???? ?? ?? ?? ? adapter = new MyAdapter();???? ?? ?? ?? ? listView.setOnItemClickListener(listener);???? ?? ?? ?? ? listView.setAdapter(adapter);???? ?? ?? ?? ? viewSwitcher.showPrevious();???? ?? ?? ?? ? ????? ?? ?? ?? ? listView.onRefreshComplete();???? ?? ?? ?}???? ???};??? };???? private OnItemClickListener listener = new OnItemClickListener() {????? ???@Override???? ???public void onItemClick(AdapterView<?> parent, View view, int position, long id) {???? ?? ?? ?if(position==1){???? ?? ?? ?? ? return;???? ?? ?? ?}???? ?? ?? ?Intent intent = new Intent(TabNewsTopActivity.this, NewsContentActivity.class);???? ?? ?? ?intent.putExtra("content_url", list.get(position-2).getLink());???? ?? ?? ?TabNewsTopActivity.this.startActivityForResult(intent, position);???? ???}??? };???? private class MyAdapter extends BaseAdapter {????? ???@Override???? ???public int getCount() {???? ?? ?? ?return list.size();???? ???}????? ???@Override???? ???public Object getItem(int position) {???? ?? ?? ?return null;???? ???}????? ???@Override???? ???public long getItemId(int position) {???? ?? ?? ?return 0;???? ???}????? ???@Override???? ???public View getView(int position, View convertView, ViewGroup parent) {???? ?? ?? ?ViewHolder holder;???? ?? ?? ?if (convertView == null) {???? ?? ?? ?? ? holder = new ViewHolder();???? ?? ?? ?? ? convertView = getLayoutInflater().inflate(R.layout.layout_news_top_item, null);???? ?? ?? ?? ? holder.tv_date = (TextView) convertView.findViewById(R.id.tv_date_news_top_item);???? ?? ?? ?? ? holder.tv_title = (TextView) convertView.findViewById(R.id.tv_title_news_top_item);???? ?? ?? ?? ? holder.tv_Description = (TextView) convertView.findViewById(R.id.tv_description_news_top_item);???? ?? ?? ?? ? convertView.setTag(holder);???? ?? ?? ?} else {???? ?? ?? ?? ? holder = (ViewHolder) convertView.getTag();???? ?? ?? ?}????? ?? ?? ?holder.tv_date.setText(list.get(position).getPubDate());???? ?? ?? ?holder.tv_title.setText(list.get(position).getTitle());???? ?? ?? ?holder.tv_Description.setText(list.get(position).getDescription());????? ?? ?? ?return convertView;???? ???}???? }???? public static class ViewHolder {???? ???TextView tv_date;???? ???TextView tv_title;???? ???TextView tv_Description;??? }???? @Override??? protected void onActivityResult(int requestCode, int resultCode, Intent data) {???? ???System.out.println("返回");???? ???super.onActivityResult(requestCode, resultCode, data);???? ??????? }}
package com.and.netease;?import android.app.Activity;import android.graphics.Bitmap;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.webkit.WebSettings;import android.webkit.WebView;import android.webkit.WebViewClient;import android.widget.ImageButton;import android.widget.ViewSwitcher;?public class NewsContentActivity extends Activity {???? ImageButton btn_back;??? WebView webView;??? String content_url;???? ViewSwitcher viewSwitcher;???? @Override??? protected void onCreate(Bundle savedInstanceState) {???? ???super.onCreate(savedInstanceState);???? ???setContentView(R.layout.layout_newscontent);???? ???initViews();??? }???? private void initViews() {???? ???btn_back = (ImageButton) findViewById(R.id.btn_newscontent_back);???? ???btn_back.setOnClickListener(listener);????? ???viewSwitcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);????? ???content_url = getIntent().getStringExtra("content_url");???? ???webView = new WebView(this);????? ???// 向ViewSwitcher中添加两个View,用来切换???? ???viewSwitcher.addView(webView);???? ???viewSwitcher.addView(getLayoutInflater().inflate(???? ?? ?? ?? ? R.layout.layout_progress_page, null));???? ???WebSettings settings = webView.getSettings();???? ???settings.setJavaScriptEnabled(true);????? ???webView.setWebViewClient(client);???? ???webView.loadUrl(content_url);??? }???? private WebViewClient client = new WebViewClient() {????? ???@Override???? ???public void onPageFinished(WebView view, String url) {???? ?? ?? ?super.onPageFinished(view, url);???? ?? ?? ?viewSwitcher.showPrevious();???? ???}????? ???@Override???? ???public void onPageStarted(WebView view, String url, Bitmap favicon) {???? ?? ?? ?super.onPageStarted(view, url, favicon);???? ?? ?? ?viewSwitcher.showNext();???? ???}????? ???@Override???? ???public boolean shouldOverrideUrlLoading(WebView view, String url) {???? ?? ?? ?return super.shouldOverrideUrlLoading(view, url);???? ???}???? };???? private OnClickListener listener = new OnClickListener() {????? ???@Override???? ???public void onClick(View v) {???? ?? ?? ?NewsContentActivity.this.setResult(RESULT_OK);???? ?? ?? ?NewsContentActivity.this.finish();???? ???}??? };???? public void onBackPressed() {???? ???if (webView.canGoBack()) {???? ?? ?? ?webView.goBack();???? ???} else {???? ?? ?? ?NewsContentActivity.this.setResult(RESULT_OK);???? ?? ?? ?NewsContentActivity.this.finish();???? ???}??? };}