안드로이드(Android) RSS 구현4 - RSS 피드 구현 제목,타이틀등 상세 구현 |
환경 : Eclipse Mars, Android 4.2.2 |
이번예제는 이전 RSS 리스트 구현에서 좀더 업그레이드 된 버전 입니다. 이전에는 RSS 제목들만 가져왔는데 이번에는 RSS 객체의 각 요소들에 대한 값들을 관리하는 VO(Value Object) RssItem 과 Feed 에 대한 설정값을 셋팅하는 RssFeed VO, 접속해서 값을 가져오고 가공하는 RssHandler 3개로 분리 하였습니다.
▼ 먼저 메인에서 사용한 내용에 대해 언급합니다. 아래에서 언급할 RssHandler 객체를 만들고 getFeed() 함수를 호출해 RssFeed 객체를 리턴 받습니다. 이곳에 RSS 호출한 정보다 모두 담겨 있게 됩니다.
RssHandler myRSSHandler = new RssHandler(); myXMLReader.setContentHandler(myRSSHandler); InputSource myInputSource = new InputSource(rssUrl.openStream()); myXMLReader.parse(myInputSource); mRssFeed = myRSSHandler.getFeed();
▼ 이렇게 getFeed() 로 리턴받은 RssFeed 객체의 각 함수들을 호출하여 메인 화면을 채웁니다. 함수명에서 알수 있듯 getTitle() 은 제목이며 getDescription() 은 RSS 전체 제목입니다. 그리고 getList() 를 호출하여 RssItem 리스트를 리턴받아 ArrayAdapter 에 셋팅합니다. 그러면 메인화면에서 리스트가 구현이 되겠죠.
private void setListView(){ TextView feedTitle = (TextView)findViewById(R.id.feedtitle); TextView feedDescribtion = (TextView)findViewById(R.id.feeddescribtion); TextView feedPubdate = (TextView)findViewById(R.id.feedpubdate); TextView feedLink = (TextView)findViewById(R.id.feedlink); feedTitle.setText(mRssFeed.getTitle()); feedDescribtion.setText(mRssFeed.getDescription()); feedPubdate.setText(mRssFeed.getPubdate()); feedLink.setText(mRssFeed.getLink()); ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>( this, android.R.layout.simple_list_item_1, mRssFeed.getList()); setListAdapter(adapter); }
▼ 메인 activity 를 구성하기 위한 레이아웃 xml 전체 내용입니다.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="RSS 피드 상세 구현" /> <TextView android:id="@+id/feedtitle" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/feeddescribtion" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/feedpubdate" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/feedlink" android:layout_width="fill_parent" android:layout_height="wrap_content" android:autoLink="web" /> <ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:id="@android:id/empty" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="No Data" /> </LinearLayout>
▼ 메인 activity 의 전체 소스 입니다.
import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import android.app.ListActivity; import android.os.AsyncTask; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.TextView; public class XmlRssInfoActivity extends ListActivity { private RssFeed mRssFeed = null; private TextView mResult; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_xml_rss_info); ProcessXmlTask xmlTask = new ProcessXmlTask(); xmlTask.execute("http://mainia.tistory.com/rss"); } private void setListView(){ TextView feedTitle = (TextView)findViewById(R.id.feedtitle); TextView feedDescribtion = (TextView)findViewById(R.id.feeddescribtion); TextView feedPubdate = (TextView)findViewById(R.id.feedpubdate); TextView feedLink = (TextView)findViewById(R.id.feedlink); feedTitle.setText(mRssFeed.getTitle()); feedDescribtion.setText(mRssFeed.getDescription()); feedPubdate.setText(mRssFeed.getPubdate()); feedLink.setText(mRssFeed.getLink()); ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>( this, android.R.layout.simple_list_item_1, mRssFeed.getList()); setListAdapter(adapter); } // AsyncTask<Params,Progress,Result> private class ProcessXmlTask extends AsyncTask<String, Void, Void> { protected Void doInBackground(String... urls) { try { URL rssUrl = new URL(urls[0]); SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance(); SAXParser mySAXParser = mySAXParserFactory.newSAXParser(); XMLReader myXMLReader = mySAXParser.getXMLReader(); RssHandler myRSSHandler = new RssHandler(); myXMLReader.setContentHandler(myRSSHandler); InputSource myInputSource = new InputSource(rssUrl.openStream()); myXMLReader.parse(myInputSource); mRssFeed = myRSSHandler.getFeed(); } catch (MalformedURLException e) { e.printStackTrace(); mResult.setText("Cannot connect RSS!"); } catch (ParserConfigurationException e) { e.printStackTrace(); mResult.setText("Cannot connect RSS!"); } catch (SAXException e) { e.printStackTrace(); mResult.setText("Cannot connect RSS!"); } catch (IOException e) { e.printStackTrace(); mResult.setText("Cannot connect RSS!"); } return null; } @Override protected void onPostExecute(Void result) { setListView(); super.onPostExecute(result); } } }
▼ 이제 VO 객체인 RssFeed 와 RssItem 에 대한 설명입니다. 먼저 RssFeed 인데 RSS 전체 정보에 대한 내용이 저장되며 각 RSS 아티클이 저장되는 RssItem 은 addItem() 함수를 통해 Vector 에 저장됩니다. 꺼낼때는 getList() 를 호출합니다.
import java.util.List; import java.util.Vector; public class RssFeed { private String title = null; private String description = null; private String link = null; private String pubdate = null; private List<RssItem> itemList; RssFeed() { itemList = new Vector<RssItem>(0); } void addItem(RssItem item) { itemList.add(item); } RssItem getItem(int location) { return itemList.get(location); } List<RssItem> getList() { return itemList; } void setTitle(String value) { title = value; } void setDescription(String value) { description = value; } void setLink(String value) { link = value; } void setPubdate(String value) { pubdate = value; } String getTitle() { return title; } String getDescription() { return description; } String getLink() { return link; } String getPubdate() { return pubdate; } }
▼ 두번째 VO 객체인 RssItem 입니다. 이곳에는 각 행에 해당하는 아티클에 대한 정보들이 저장되겠죠. 글제목, 글 내용, 발행일자등등 이 저장되는 VO 입니다. 이 값들을 List 객체에 추가해 메인화면에서 리스트를 구성하는 것이죠.
public class RssItem { private String title = null; private String description = null; private String link = null; private String pubdate = null; RssItem() { } void setTitle(String value) { title = value; } void setDescription(String value) { description = value; } void setLink(String value) { link = value; } void setPubdate(String value) { pubdate = value; } String getTitle() { return title; } String getDescription() { return description; } String getLink() { return link; } String getPubdate() { return pubdate; } @Override public String toString() { return title; } }
▼ 다음은 RSS XML 값들을 파싱해서 VO 객체에 셋팅하는 역할을 하는 RssHandler 입니다. SAX API 인 DefaultHandler 를 상속받아 만들었으며 Characters() 함수에서 요소에 값이 무엇인지 판단하여 VO 에 셋팅합니다.
import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class RssHandler extends DefaultHandler { final int STATE_UNKNOW = 0; final int STATE_TITLE = 1; final int STATE_DESCRIPTION = 2; final int STATE_LINK = 3; final int STATE_PUBDATE = 4; int currentState = STATE_UNKNOW; RssFeed feed; RssItem item; boolean itemFound = false; RssHandler() { } RssFeed getFeed() { return feed; } @Override public void startDocument() throws SAXException { feed = new RssFeed(); item = new RssItem(); } @Override public void endDocument() throws SAXException { } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (localName.equalsIgnoreCase("item")) { itemFound = true; item = new RssItem(); currentState = STATE_UNKNOW; } else if (localName.equalsIgnoreCase("title")) { currentState = STATE_TITLE; } else if (localName.equalsIgnoreCase("description")) { currentState = STATE_DESCRIPTION; } else if (localName.equalsIgnoreCase("link")) { currentState = STATE_LINK; } else if (localName.equalsIgnoreCase("pubdate")) { currentState = STATE_PUBDATE; } else { currentState = STATE_UNKNOW; } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (localName.equalsIgnoreCase("item")) { feed.addItem(item); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { String strCharacters = new String(ch, start, length); if (itemFound == true) { // "item" tag found, it's item's parameter switch (currentState) { case STATE_TITLE: item.setTitle(strCharacters); break; case STATE_DESCRIPTION: item.setDescription(strCharacters); break; case STATE_LINK: item.setLink(strCharacters); break; case STATE_PUBDATE: item.setPubdate(strCharacters); break; default: break; } } else { // not "item" tag found, it's feed's parameter switch (currentState) { case STATE_TITLE: feed.setTitle(strCharacters); break; case STATE_DESCRIPTION: feed.setDescription(strCharacters); break; case STATE_LINK: feed.setLink(strCharacters); break; case STATE_PUBDATE: feed.setPubdate(strCharacters); break; default: break; } } currentState = STATE_UNKNOW; } }
'안드로이드 개발' 카테고리의 다른 글
안드로이드(Android) 경고 - Custom view… overrides onTouchEvent but not performClick (0) | 2014.11.28 |
---|---|
안드로이드(Android) onDraw 함수를 이용해 화면에 비트맵이미지, 도형 그리기 (0) | 2014.11.27 |
안드로이드(Android) 코드경고 – Avoid object allocations during draw/layout operations (preallocate and reuse instead) 해제 하기 (0) | 2014.11.26 |
안드로이드(Android) RSS 구현5 - RSS 제목별 상세내용 구현 (1) | 2014.11.25 |
안드로이드(Android)RSS 구현3 - RSS 피드 읽어서 ListView 로 제목 표현하기 (0) | 2014.11.23 |
안드로이드(Android) RSS 구현2 - XML 파싱클래스를 이용해서 RSS Reader 구현하기 (5) | 2014.11.22 |
안드로이드(Android) RSS 구현1 - XmlResourceParser 를 이용하여 XML 파싱하기 (0) | 2014.11.21 |
안드로이드(Android) Java 코드에서 색깔값 화면에 입히기 (0) | 2014.11.20 |