개발일지/빅데이터 댓글 시각화 프로젝트

[개발일지] ArrayList<hashmap> 형태 활용하기

Emil :) 2020. 11. 23. 11:40
728x90
반응형
이 글은 Notion에서 작성 후 재편집한 포스트입니다.

목차

오늘의 목표


  1. MainActivity에서 Intent로 넘겨주기
  2. 네트워크 상태 확인하고 연결 안되있으면 토스트 메세지 띄우고 리턴하기
  3. fragment결과화면 구성하기

참고


stackoverrun.com/ko/q/3484098

 

ArrayList의 HashMap 키에서 모든 값 가져 오기 Java

좋은 하루였습니다. 지금은 혼란스러워서 (뇌의 동결!) 무언가가 누락 된 것 같습니다. 내가 HashMap로 채울 ArrayList가 있습니다. 이제는 내 HashMap과 arraylist를 넣었습니다. Map.put(DATE, value1); Map.put(VAL

stackoverrun.com

진행 과정


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, "시간대별 댓글");

이렇게 하면 그래프가 다음과 같이 출력된다.

아주 맘에든다 호흫힣흐핳

오늘의 결과


구독 및 하트는 정보 포스팅 제작에 큰 힘이됩니다♡

728x90
반응형