도전과제 20 : RSS 조회 내용을 그리드뷰로 보여주기 (Do it Android 앱 프로그래밍) [JAVA]
반응형

 

도전과제 20

RSS 사이트를 조회하여 최신 기사를 받은 후 격자 모양으로 보여주는 기능을 만들어 보세요. rss 사이트는 연예, 경제 등 어떤 내용이든 상관없습니다.

  1. RSS 기사를 조회할 수 있는 화면을 구성합니다.
  2. 화면의 아래쪽에 [조회] 버튼을 배치하고 나머지 공간은 리싸이클러뷰가 차지하도록 합니다.
  3. [조회] 버튼을 누르면 지정한 RSS 사이트를 조회하여 최신 기사를 가져온 후 리사이클러뷰에 표시합니다.
  4. RSS 사이트 주소는 미리 소스 코드에 설정합니다.
  5. 리싸이클러뷰의 각 아이템에 보일 데이터로는 아이콘과 제목, 내용이 표시되도록 합니다.

참고할점
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

 

howtolivelikehuman/DoitAndroid

Do it Android programing (JAVA). Contribute to howtolivelikehuman/DoitAndroid development by creating an account on GitHub.

github.com

 

 

반응형