이 글은 Notion에서 작성 후 재편집한 포스트입니다.
목차
오늘의 목표
- MainActivity에서 Intent로 넘겨주기
- 네트워크 상태 확인하고 연결 안되있으면 토스트 메세지 띄우고 리턴하기
- fragment결과화면 구성하기
참고
진행 과정
1. MainActivity에서 Intent로 데이터 넘겨주기
값을 넘겨줄 intent를 설정해주도록 하자.
//결과값 넘겨줄 Intent 선언
Intent resultIntent;
...
//onCreate 에 넣어주기
//결과화면으로 넘겨줄 Intent 생성
resultIntent = new Intent(MainActivity.this.getApplicationContext(), ResultActivity.class);
//해당 araay의 hashmap에 데이터가 삽입되면 다음 putExtra로 넣어주기
resultIntent.putExtra("tenws", tnews);
resultIntent.putExtra("relevantArticle", relevantArticle);
resultIntent.putExtra("timeAnalysis", timeAnalysis);
resultIntent.putExtra("keywordRank", keywordRank);
이제 다음 액티비티를 실행시켜 줄 때, asyncTask의 onPostExecute 에서 다음 액티비티를 실행시켜줘야 한다.
public class GETAsyncTask extends AsyncTask<String, Void, String>{
ProgressDialog progressDialog;
@Override
protected void onPostExecute(String s) {
JsonParsing();
startActivity(resultIntent);
super.onPostExecute(s);
}
}
ResultActivity에선 공통으로 표기되는 기사 제목을 바꿔주고, fragment에서 사용될 데이터를 bundle을 이용해서 넘겨준다.
그리고 Viewpager를 세팅해주도록 하자.
public class ResultActivity extends AppCompatActivity {
private ViewPager mViewPager;
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
ArrayList<HashMap<String, String>> tnewsArrayList;
ArrayList<HashMap<String, String>> timeAnalysisArrayList;
ArrayList<HashMap<String, String>> relevantArticleArrayList;
ArrayList<HashMap<String, String>> keywordRankArrayList;
ArrayList<HashMap<String, String>> emotionAnalysisArrayList;
ArrayList<HashMap<String, String>> emotionCommentsArrayList;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
HashMap<String,String> hashMap = new HashMap<>();
Intent intent = getIntent();
tnewsArrayList = (ArrayList<HashMap<String, String>>) intent.getSerializableExtra("tnews");
timeAnalysisArrayList = (ArrayList<HashMap<String, String>>) intent.getSerializableExtra("timeAnalysis");
relevantArticleArrayList = (ArrayList<HashMap<String, String>>) intent.getSerializableExtra("relevantArticle");
keywordRankArrayList = (ArrayList<HashMap<String, String>>) intent.getSerializableExtra("keywordRank");
emotionAnalysisArrayList = (ArrayList<HashMap<String, String>>) intent.getSerializableExtra("emotionAnalysis");
emotionCommentsArrayList = (ArrayList<HashMap<String, String>>) intent.getSerializableExtra("emotionComments");
TextView newsTitle = findViewById(R.id.articleTitle);
newsTitle.setText(emotionAnalysisArrayList.get(0).get("title"));
//워드클라우드 이미지 따로 받아오기
String wordcloud = getIntent().getStringExtra("wordcloud");
hashMap.put("wordcloud", wordcloud);
keywordRankArrayList.add(hashMap);
hashMap = new HashMap<>();
hashMap.put("flag","true");
String simArticleImg1 = getIntent().getStringExtra("simArticleImg1");
hashMap.put("simArticleImg1", simArticleImg1);
String simArticleImg2 = getIntent().getStringExtra("simArticleImg2");
hashMap.put("simArticleImg2", simArticleImg2);
String simArticleImg3 = getIntent().getStringExtra("simArticleImg3");
hashMap.put("simArticleImg3", simArticleImg3);
relevantArticleArrayList.add(hashMap);
mViewPager = findViewById(R.id.layout_viewPager);
setupViewPager(mViewPager);
TabLayout tabLayout = findViewById(R.id.layout_tab);
tabLayout.setupWithViewPager(mViewPager);
}
public void setupViewPager(ViewPager viewPager) {
Fragment fragmentTotal = new FragmentTotal();
Fragment fragmentKeyword = new FragmentKeyword();
Fragment fragmentEmotion = new FragmentEmotion();
Fragment fragmentEtc = new FragmentEtc();
//프래그먼트로 넘겨줄 arraylist친구들
Bundle bundle = new Bundle();
bundle.putSerializable("tnewsArrayList", tnewsArrayList);
bundle.putSerializable("timeAnalysisArrayList", timeAnalysisArrayList);
bundle.putSerializable("relevantArticleArrayList", relevantArticleArrayList);
bundle.putSerializable("keywordRankArrayList", keywordRankArrayList);
bundle.putSerializable("emotionAnalysisArrayList", emotionAnalysisArrayList);
bundle.putSerializable("emotionCommentsArrayList", emotionCommentsArrayList);
fragmentTotal.setArguments(bundle);
fragmentKeyword.setArguments(bundle);
fragmentEmotion.setArguments(bundle);
fragmentEtc.setArguments(bundle);
adapter.addFragment(fragmentTotal, "종합");
adapter.addFragment(fragmentKeyword, "키워드 분석");
adapter.addFragment(fragmentEmotion, "감정 분석");
adapter.addFragment(fragmentEtc, "기타 정보");
viewPager.setAdapter(adapter);
}
}
2. 네트워크 연결 안되면 토스트 메시지로 튕겨주기
//인터넷 연결 체크
int status = NetworkStatus.getConnectivityStatus(getApplicationContext());
if(status == NetworkStatus.TYPE_MOBILE){
}else if (status == NetworkStatus.TYPE_WIFI){
}else {
Toast.makeText(getApplicationContext(),"인터넷을 먼저 연결해주세요.", Toast.LENGTH_SHORT).show();
return;
}
3. fragment 결과화면 구성하기
package fragment;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.ViewPager;
import com.example.myapplication.R;
import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.charts.PieChart;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.data.PieData;
import com.github.mikephil.charting.data.PieDataSet;
import com.github.mikephil.charting.data.PieEntry;
import com.github.mikephil.charting.formatter.IndexAxisValueFormatter;
import com.github.mikephil.charting.formatter.ValueFormatter;
import com.github.mikephil.charting.interfaces.datasets.IPieDataSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
//import com.example.myapplication.ResultActivity;
public class FragmentTotal extends Fragment {
ViewPager viewPager;
ArrayList<HashMap> tnewsArrayList;
ArrayList<HashMap> timeAnalysisArrayList;
ArrayList<HashMap> relevantArticleArrayList;
public void Fragment_Total() {
}
public void sexRateChart(View view) {
PieChart sexRateChart;
sexRateChart = view.findViewById(R.id.sexRateChart);
sexRateChart.setUsePercentValues(true);
sexRateChart.getDescription().setEnabled(true);
sexRateChart.setExtraOffsets(5f, 10f, 5f, 5f);
sexRateChart.setDragDecelerationFrictionCoef(0.95f);
sexRateChart.setDrawHoleEnabled(false);
sexRateChart.setHoleColor(Color.BLACK);
sexRateChart.setTransparentCircleRadius(61f);
ArrayList sexValues = new ArrayList();
HashMap<String, String> map = tnewsArrayList.get(0);
sexValues.add(new PieEntry(72.0f, "남성"));
sexValues.add(new PieEntry(28.0f, "여성"));
sexRateChart.animateY(5000, Easing.EaseInOutCubic);
final int[] sexColors = {
Color.parseColor("#2b88f2"),
Color.parseColor("#e7b7cc")
};
ArrayList<Integer> colors = new ArrayList<Integer>();
for (int c : sexColors)
colors.add(c);
PieDataSet sexDataSet = new PieDataSet((List) sexValues, "성별");
sexDataSet.setSliceSpace(3.0F);
sexDataSet.setSelectionShift(2.0F);
sexDataSet.setColors(colors);
PieData sexData = new PieData((IPieDataSet) sexDataSet);
sexData.setValueTextSize(10.0F);
sexData.setValueTextColor(Color.BLACK);
sexRateChart.setData(sexData);
sexRateChart.invalidate();
}
public void ageRateChart(View view) {
BarChart ageRateChart = view.findViewById(R.id.ageRateChart);
ageRateChart.setExtraOffsets(5.0f, 10.0f, 5.0f, 5.0f);
final ArrayList ageValues = new ArrayList();
HashMap<String, String> map = tnewsArrayList.get(0);
ageValues.add(new BarEntry(0.0f, 10.0f, "10대"));
ageValues.add(new BarEntry(1.0F, 30.0f, "20대"));
ageValues.add(new BarEntry(2.0F, 40.1f, "30대"));
ageValues.add(new BarEntry(3.0F, 64.0f, "40대"));
ageValues.add(new BarEntry(4.0F, 35.0f, "50대"));
ageValues.add(new BarEntry(5.0F, 5.0f, "60대 이상"));
final ArrayList<String> xLabel = new ArrayList<>();
xLabel.add("10대");
xLabel.add("20대");
xLabel.add("30대");
xLabel.add("40대");
xLabel.add("50대");
xLabel.add("60대 이상");
XAxis xAxis = ageRateChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setValueFormatter(new IndexAxisValueFormatter(xLabel));
xAxis.setGranularity(1f);
xAxis.setGranularityEnabled(true);
ageRateChart.animateY(5000, Easing.EaseInOutCubic);
final int[] ageColors = {
Color.parseColor("#d4d4d4"),
Color.parseColor("#d4d4d4"),
Color.parseColor("#d4d4d4"),
Color.parseColor("#cf16f2"),
Color.parseColor("#d4d4d4"),
Color.parseColor("#d4d4d4"),
};
ArrayList<Integer> colors = new ArrayList<Integer>();
for (int c : ageColors)
colors.add(c);
BarDataSet ageDataSet = new BarDataSet(ageValues, " 연령대");
ageDataSet.setColors(colors);
BarData ageData = new BarData(ageDataSet);
ageData.setBarWidth(1f);
ageRateChart.setData(ageData);
ageRateChart.setFitBars(true);
ageRateChart.invalidate();
}
public void timeLineChart(View view) {
ArrayList timeValues = new ArrayList();
int[] timeLineData = new int[24];
//각 시간대별 댓글 수를 Array에 삽입
for(int i = 0; i < timeAnalysisArrayList.size(); i++){
Object temp = timeAnalysisArrayList.get(i).get("time");
String time = temp.toString();
temp = timeAnalysisArrayList.get(i).get("count");
String count = temp.toString();
int commTime = Integer.parseInt(time);
int commCount = Integer.parseInt(count);
timeLineData[commTime] = commCount;
}
for(int i = 0 ; i < timeLineData.length; i++){
timeValues.add(new Entry(i, timeLineData[i]));
}
LineChart timeLineChart = view.findViewById(R.id.timeLineChart);
LineDataSet setTime = new LineDataSet(timeValues, "시간대별 댓글");
setTime.setAxisDependency(YAxis.AxisDependency.LEFT);
setTime.setColor(Color.parseColor("#c39797"));
setTime.setLineWidth(6f);
ArrayList timeDataset = new ArrayList();
timeDataset.add(setTime);
final ArrayList<String> xLabel = new ArrayList<>();
for(int i = 0; i < 24; i++){
xLabel.add(String.format("%02d",i) + "시");
}
XAxis xAxis = timeLineChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
ValueFormatter formatter = new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
return xLabel.get((int) value);
}
};
xAxis.setGranularity(1f); // minimum axis-step (interval) is 1
xAxis.setValueFormatter(formatter);
LineData timeData = new LineData((List) timeDataset);
timeLineChart.animateXY(5000, 5000, Easing.EaseInOutCubic);
timeLineChart.setData(timeData);
timeLineChart.invalidate();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_total, container, false);
Bundle bundle = getArguments();
tnewsArrayList = (ArrayList<HashMap>) bundle.getSerializable("tnewsArrayList");
timeAnalysisArrayList = (ArrayList<HashMap>) bundle.getSerializable("timeAnalysisArrayList");
sexRateChart(view);
ageRateChart(view);
timeLineChart(view);
return view;
}
}
bundle로 넘어온 친구들을 전역변수로 설정해둔 ArrayList에 넣어주고, 필요할 때마다 값을 가져와서 사용했다.
오늘 개발하면서 핵심은 시간대 그래프를 짜주는 부분인거같다! 이 부분은 처음에 하드코딩으로 대충 데이터만 욱여놨었다. 이런식으로..
HashMap<String, String> map1 = timeAnalysisArrayList.get(0);
HashMap<String, String> map2 = timeAnalysisArrayList.get(1);
HashMap<String, String> map3 = timeAnalysisArrayList.get(2);
HashMap<String, String> map4 = timeAnalysisArrayList.get(3);
Entry timeLine1 = new Entry(0.0F, Float.parseFloat(map1.get("count")));
timeValues.add(timeLine1);
Entry timeLine2 = new Entry(1.0F, Float.parseFloat(map2.get("count")));
timeValues.add(timeLine2);
Entry timeLine3 = new Entry(2.0F, Float.parseFloat(map3.get("count")));
timeValues.add(timeLine3);
Entry timeLine4 = new Entry(3.0F, Float.parseFloat(map4.get("count")));
timeValues.add(timeLine4);
아주아주아주아주아주 쓰레기같은 코드라고 할 수 있다. (물론 지금 짠 코드도 최적이라곤 생각하지않는다. 더 고민해야한다.)
Null 예외 처리에 굉~장히 취약하기 때문이다.
실제로 넘어오는 arraylist의 크기가 4 이하인 경우 nullPointerException이 밥먹듯이 일어났다. 그래서 다음과 같이 처리했다.
for(int i = 0; i < timeAnalysisArrayList.size(); i++){
Object temp = timeAnalysisArrayList.get(i).get("time");
String time = temp.toString();
temp = timeAnalysisArrayList.get(i).get("count");
String count = temp.toString();
int commTime = Integer.parseInt(time);
int commCount = Integer.parseInt(count);
timeLineData[commTime] = commCount;
}
내가 필요한 것은 시간대 그래프를 그려줄 "시간" 과 해당 시간에 댓글이 입력된 "갯수" 였다. 즉, time과 count가 timeAnalysisArrayList안에 hashmap 형태로 들어있다.
여기서 위와 같이 변수를 가져오고 할당해준다음 for문 밖에 선언되어있는 timeLineData[] 배열에 넣어줬다.
그리고 이 배열을 그래프에 그려주는데 필요한 timeValues 라는 arraylist에 넣어주고, mpandroidchart의 Linedataset에 넣어줬다.
for(int i = 0 ; i < timeLineData.length; i++){
timeValues.add(new Entry(i, timeLineData[i]));
}
LineChart timeLineChart = view.findViewById(R.id.timeLineChart);
LineDataSet setTime = new LineDataSet(timeValues, "시간대별 댓글");
이렇게 하면 그래프가 다음과 같이 출력된다.
아주 맘에든다 호흫힣흐핳
오늘의 결과
구독 및 하트는 정보 포스팅 제작에 큰 힘이됩니다♡
'개발일지 > 빅데이터 댓글 시각화 프로젝트' 카테고리의 다른 글
[개발일지] for문으로 xml resource 가져오기(feat.getIdentifier()) (0) | 2020.12.10 |
---|---|
[Android] Tablayout, Viewpager 사용하기 (0) | 2020.11.01 |
[Python, MySQL] txt파일 csv파일 변환 및 데이터 가공 (feat. db 연동) (0) | 2020.07.28 |
[에러] list indices must be integers or slices, not str (0) | 2020.07.11 |
[Python] 네이버 기사 댓글 크롤링하기 2.0v (0) | 2020.07.11 |