jsoup으로 JTBC 뉴스 RSS 읽어오는 예제 - 코드 전체보기 [Android]
게임 개발 초보자/안드로이드 활용 예제2018. 6. 25. 16:35
JTBC의 RSS 서비스 링크
http://news.jtbc.joins.com/Etc/RssService.aspx
<RSS 서비스 메인>
<속보 RSS xml>
Jsoup을 이용해 rss 서비스 주소와 이름을 가져오고 이걸로 안드로이드에 Tab layout(탭)으로 만든다
원하는 메뉴(속보, 정치, 경제, 사회, 국제, 문화, 연예, 스포츠, 풀영상, 뉴스랭킹, 뉴스룸, 아침&, 뉴스현장, 정치부회의)를 누르면
해당 서비스 주소에 나오는 뉴스를 ListView(리스트)로 보여준다
실행 결과 화면
프로젝트 파일 구조
[XML 파일]
1. activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/appbar_padding_top"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:title="@string/app_name">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
2. fragment_jtbc.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".JTBCFragment">
<ListView
android:id="@+id/NewsList"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>
3. news_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/titleTV"
android:layout_alignParentLeft="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:textSize="10pt"
android:text="뉴스 제목"/>
<TextView
android:id="@+id/dateTV"
android:layout_alignParentRight="true"
android:layout_alignBottom="@+id/titleTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dp"
android:textSize="6pt"
android:text="뉴스 날짜"/>
</RelativeLayout>
<TextView
android:id="@+id/descTV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="25dp"
android:textSize="8pt"
android:text="뉴스 간략 설명"/>
<View
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_gravity="center"
android:background="#cad8e6"/>
</LinearLayout>
[JAVA 파일]
코드만 붙여넣기 할 경우 맨 위에 package로 시작하는 한줄만 남겨놓고 그 밑에 내용 전체를 이 코드로 변경해준다
1. MainActivity
import android.os.AsyncTask;
import android.support.design.widget.TabLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ViewPager mViewPager;
private TabLayout tabLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mViewPager = (ViewPager) findViewById(R.id.container);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
//어플이 실행되면 RSS서비스 메인 주소에 접근한다
String rssURL = "http://news.jtbc.joins.com/Etc/RssService.aspx";
new CategoryTask().execute(rssURL);
}
class CategoryTask extends AsyncTask<String,Void,Void> {
List<Category> categories; //읽어온 데이터를 리스트로 저장
//실제 CategoryTask의 주요 작업
@Override
protected Void doInBackground(String... strings) {
String rssURL = strings[0];
try {
Document document = Jsoup.connect(rssURL).get();
Elements elements = document.select("table.common_table tbody tr");
Category category;
//한줄씩 가져와서 Category에 저장
for (Element element : elements) {
//title
category = new Category();
category.setTitle(element.select("th").get(0).text());
category.setUrl(element.select("a").get(0).text());
//한줄을 다 읽었으면 categories에 다시 보관
categories.add(category);
}
Log.d("목록 다 읽었는지 찍어볼게요",categories.toString());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//가장 먼저 실행
@Override
protected void onPreExecute() {
super.onPreExecute();
categories = new ArrayList<>();
}
//doInBackground가 끝나면 실행
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//Category 개수만큼 반복
for (Category c : categories) {
tabLayout.addTab(tabLayout.newTab());
}
TabPagerAdapter adapter = new TabPagerAdapter
(getSupportFragmentManager(),tabLayout.getTabCount(),categories);
mViewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(mViewPager);
}
}
}
2. Category
public class Category {
private String title;
private String url;
//Getter&Setter 추가
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getUrl() { return url; }
public void setUrl(String url) { this.url = url; }
//toString 추가(생략 가능)
@Override
public String toString() { return title+": "+url; }
}
3. TabPagerAdapter
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import java.util.List;
public class TabPagerAdapter extends FragmentStatePagerAdapter {
private int tabCount;
private List<Category> categories;
public TabPagerAdapter(FragmentManager fm, int tabCount, List<Category> categories) {
super(fm);
this.tabCount = tabCount;
this.categories = categories;
}
@Override
public Fragment getItem(int position) {
Category category = categories.get(position);
Fragment fragment = JTBCFragment.newInstance(category.getTitle(),category.getUrl());
return fragment;
}
@Override
public int getCount() {
return tabCount;
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return categories.get(position).getTitle();
}
}
4. JTBCFragment
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class JTBCFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
private ListView listView;
public JTBCFragment() {
}
public static JTBCFragment newInstance(String param1, String param2) {
JTBCFragment fragment = new JTBCFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_jtbc, container, false);
listView = view.findViewById(R.id.NewsList);
new NewsTask().execute();
return view;
}
class NewsTask extends AsyncTask<Void,Void,Void>{
List<NewsDTO> newsList;
@Override
protected Void doInBackground(Void... voids) {
try {
Document document = Jsoup.connect(mParam2).get();
Elements elements = document.select("item");
for (Element element : elements) {
NewsDTO data = new NewsDTO();
Elements e = element.select("title");
if (e != null && e.size()>0)
data.setTitle(e.get(0).text());
e = element.select("link");
if (e != null && e.size()>0)
data.setLink(e.get(0).text());
e = element.select("description");
if (e != null && e.size()>0)
data.setDescription(e.get(0).text());
e = element.select("pubDate");
if (e != null && e.size()>0)
data.setPubDate(e.get(0).text());
newsList.add(data);
}
Log.d("뉴스 다 읽었는지 찍어볼게요",newsList.toString());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
newsList = new ArrayList<>();
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
NewsAdapter adapter = new NewsAdapter(getContext(),newsList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(newsList.get(position).getLink()));
startActivity(intent);
}
});
}
}
}
5. NewsDTO
public class NewsDTO {
private String title;
private String link;
private String description;
private String pubDate;
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 "뉴스제목" + title + " " + pubDate + " 발행일";
}
}
6. NewsView
import android.content.Context;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.TextView;
public class NewsView extends LinearLayout {
//뉴스 1개 보여질 xml에서 사용하는 요소
TextView titleTV, dateTV, descTV;
public NewsView(Context context, NewsDTO data) {
super(context);
LayoutInflater inflater = (LayoutInflater) context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.news_item,this,true);
titleTV = findViewById(R.id.titleTV);
dateTV = findViewById(R.id.dateTV);
descTV = findViewById(R.id.descTV);
setNews(data);
}
public void setNews(NewsDTO data) {
//titleTV 세팅
if(data.getTitle()!=null && data.getTitle().trim().length()>0)
titleTV.setText(data.getTitle());
else
titleTV.setText("");
//dateTV 세팅
if(data.getPubDate()!=null && data.getPubDate().trim().length()>0)
dateTV.setText(data.getPubDate());
else
dateTV.setText("");
//descTV 세팅
if(data.getDescription()!=null && data.getDescription().trim().length()>0)
descTV.setText(data.getDescription());
else
descTV.setText("");
}
}
7. NewsAdapter
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.List;
public class NewsAdapter extends BaseAdapter {
private Context context;
private List<NewsDTO> list;
public NewsAdapter(Context context, List<NewsDTO> list) {
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
NewsDTO data = list.get(position);
NewsView view = null;
//이전에 만들어 놓은 View가 없으면
if (convertView == null) {
//NewsView모양으로 새로 만들고
view = new NewsView(context, data);
//이전에 만들어 놓은 View가 있으면
} else {
//만들어놨던 View(convertView)를 재활용해서 내용만 바꾼다
view = (NewsView) convertView;
view.setNews(data);
}
return view;
}
}
'게임 개발 초보자 > 안드로이드 활용 예제' 카테고리의 다른 글
jsoup으로 JTBC 뉴스 RSS 읽어오는 예제 - 3 [Android] (0) | 2018.06.25 |
---|---|
jsoup으로 JTBC 뉴스 RSS 읽어오는 예제 - 2 [Android] (0) | 2018.06.22 |
jsoup으로 JTBC 뉴스 RSS 읽어오는 예제 - 1 [Android] (0) | 2018.06.22 |