도전과제 20
RSS 사이트를 조회하여 최신 기사를 받은 후 격자 모양으로 보여주는 기능을 만들어 보세요. rss 사이트는 연예, 경제 등 어떤 내용이든 상관없습니다.
- RSS 기사를 조회할 수 있는 화면을 구성합니다.
- 화면의 아래쪽에 [조회] 버튼을 배치하고 나머지 공간은 리싸이클러뷰가 차지하도록 합니다.
- [조회] 버튼을 누르면 지정한 RSS 사이트를 조회하여 최신 기사를 가져온 후 리사이클러뷰에 표시합니다.
- RSS 사이트 주소는 미리 소스 코드에 설정합니다.
- 리싸이클러뷰의 각 아이템에 보일 데이터로는 아이콘과 제목, 내용이 표시되도록 합니다.
참고할점
RSS 사이트를 조회해서 가져온 데이터는 태그로 구성되므로 RSS 조회 결과 문서를 파싱한 후 각 기사를 리싸이클러뷰의 아이템으로 추가해야 합니다.
풀이
레이아웃은 위에 주소를 넣을 수 있는 창과, 기사들을 띄울 리싸이클러뷰, 조회버튼으로 구성하였다. 또한 리사이클러뷰에 표시될 각 아이템 역시 따로 리니어레이아웃 내에 카드뷰 형태로 정의해두었다.
뉴스를 정의한 News객체와, 이를 RecyclerView로 표현하기 위한 NewsAdapter 객체역시 정의해준다. NewsAdapter 객체는 RecyclerView.Adapter<NewsAdapter.ViewHolder>를 상속한 객체로, 객체 내에 UI를 나타낼 ViewHolder역시 정의해두어야 한다. 이후 메인 액티비티에서 GridLayoutManger를 통해 RecyclerView를 적용시키고, RecyclerView에 어댑터를 적용함으로써 전체적인 동작을 만들 수 있다.
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
NewsAdapter adapter;
EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
editText = findViewById(R.id.editText);
GridLayoutManager layoutManager = new GridLayoutManager(this,2);
recyclerView.setLayoutManager(layoutManager);
adapter = new NewsAdapter();
recyclerView.setAdapter(adapter);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
getRSS(editText.getText().toString());
}
});
}
private void getRSS(String s) {
// AsyncTask 를 이용하여 RSS News 를 읽어오기
XMLParsing vp = new XMLParsing(s);
adapter.setItems(vp.getData());
adapter.notifyDataSetChanged();
}
}
그렇다면 이제 RSS를 통해 기사의 내용만 가져올 일이 남았다. 이는 XMLParsing 객체에 따로 정의해 두었다. 메인 액티비티에서는 이 객체를 통해 어댑터에 Item(News)를 채워넣는다. 우선 파싱을 하기 전에 RSS에 대해 살펴보자.
RSS(Rich Site Summary)는 뉴스나 블로그 사이트에서 주로 사용하는 콘텐츠 표현 방식이다. 형식이 정해져 있는데, 잘 보면 개별 내용들이 <item>으로 묶여 있고, 그 안에 <title>,<link> 등 정해진 태그들이 있다. 이제 이 정해진 태그들을XmlPullParser 객체를 이용하여 원하는 태그들만 뽑아서 쓰면 된다.
이때 XmlPullparser에 InputStream으로 원하는 사이트를 넣어주고, getEventType을 통해 문서의 종료지점을 계속 확인하면서 파싱해 나아가면 된다.
protected ArrayList<News> doInBackground(Object... objects) {
ArrayList<News> list = new ArrayList<News>();
try {
URL url = new URL(URLst);
// RSS의 값들을 XmlParser에 연결.
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser parser = factory.newPullParser();
BufferedInputStream bis = new BufferedInputStream(url.openStream());
parser.setInput(bis, null); //InputStream과 String을 인자로 받음.
// getEventType()으로 문서의 시작과 끝 확인가능
int parserEvent = parser.getEventType();
while (parserEvent != XmlPullParser.END_DOCUMENT) { //문서가 끝날때까지 동작해라.
switch (parserEvent) {
case XmlPullParser.START_TAG: // TAG 시작. 예시) <title> 태그
tag = parser.getName();
if(tag.equals("item")){ // news 들만 가져오기 위한 boolean 확인
isItem = true;
}
break;
case XmlPullParser.TEXT: // TAG 안의 문자열. 예시) <title> 과 </title> 사이의 문자열
if(isItem) {
if (tag.equals("title")) { // title TAG 확인
title = parser.getText();
}
if (tag.equals("link")) { // link TAG 확인
link = parser.getText();
}
if (tag.equals("description")) { // description TAG 확인
description = parser.getText();
}
if (tag.equals("dc:date")) { // dc:date TAG 확인
time = parser.getText();
}
}
break;
case XmlPullParser.END_TAG: // TAG 종료. 예시) </title> 태그
tag = parser.getName();
if(tag.equals("item")){ // news 태그 종료확인
list.add(new News(title, description, link, time)); // 한개의 news 를 저장
title =""; //다시 모든 값들 초기화.
link ="";
description ="";
time ="";
isItem = false;
}
tag = ""; // tag 값 초기화 하자
break;
}
// 다음 TAG 로 이동
// 예시) </title>의 다음 Tag 인 <link>로 이동.
parserEvent = parser.next();
}
} catch (Exception e){
e.printStackTrace();
}
return list;
}
XML 파싱에 대한 부분은 https://junuda.tistory.com/25 << 여기서 코드를 많이 참고했다.
결과
전체 소스코드 : https://github.com/howtolivelikehuman/DoitAndroid/tree/master/DoitMission_20/app/src/main
'코딩 > Do it Android [JAVA]' 카테고리의 다른 글
도전과제 23 : 페인트보드 앱의 설정 기능 만들기 (Do it Android 앱 프로그래밍) [JAVA] (0) | 2020.08.31 |
---|---|
도전과제 21,22 : 책 정보 저장과 조회 기능 만들기 (Do it Android 앱 프로그래밍) [JAVA] (0) | 2020.08.31 |
도전과제 19 : 웹으로 가져온 데이터 보여주기 (Do it 안드로이드 앱 프로그래밍)[JAVA] (0) | 2020.08.30 |
도전과제 18 : 앨범의 사진을 애니메이션으로 보여주기 (Do it 안드로이드 앱 프로그래밍)[JAVA] (0) | 2020.08.29 |
도전과제 17 : 패널을 번갈아가며 보여주기 (Do it 안드로이드 앱 프로그래밍) [JAVA] (0) | 2020.08.29 |
Comment