Android

Json (제이슨) 형식의 데이터 파싱하고 어댑터를 사용하기

567Rabbit 2024. 6. 10. 16:41

 

 

activity_main.xml 작성하기

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <Button
            android:id="@+id/btnAdd"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerInParent="false"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginBottom="10dp"
            android:text="직원 추가"
            android:textSize="30sp" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/btnAdd" />

        <ProgressBar
            android:id="@+id/progressBar2"
            style="?android:attr/progressBarStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/btnAdd"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="316dp"
            android:visibility="visible" />

    </RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

 

 

JSON 데이터를 파싱하고 RecyclerView로 표시하는 과정

 

  1. JSON 데이터 수신 및 파싱 : 서버에서 JSON 형식의 데이터를 수신, 파싱 라이브러리(Gson, Jackson 등)를 사용하여 JSON 데이터를 파싱하여        Java 객체로 변환
  2. 어댑터 생성 : RecyclerView.Adapter를 확장하여 커스텀 어댑터를 만들고 어댑터 내에서 ViewHolder 클래스를 정의한 후, onBindViewHolder 메서드에서 데이터를 뷰에 바인딩
  3. RecyclerView 설정 : RecyclerView에 레이아웃 매니저를 설정(예: LinearLayoutManager, GridLayoutManager 등) 후 RecyclerView에 어댑터를 설정

 

 

 

Json 데이터 파싱하고, 어댑터(adapter) 사용하여 RecyclerView로 만들기

 

 

JSON 데이터 파싱하기?

= 제이슨으로 받아온 데이터를 꺼내와 사용하는 것이다.  try 안에서 코드를 입력해야 한다.

 

 

RecyclerView는 Android에서 대량의 데이터를 효율적으로 표시하기 위한 뷰이다. RecyclerView는 스크롤 시 뷰를 재사용(recycle)하여 메모리 사용량을 줄이고, 성능을 향상시킨다. 또한 다양한 레이아웃 매니저를 통해 리스트, 그리드, 스태거드 레이아웃 등을 쉽게 구현할 수 있으며 애니메이션 지원 기능이 있다.

 

 

어댑터(Adapter)는 데이터 소스(예: JSON 데이터)와 RecyclerView를 연결하는 역할을 하며 데이터 항목을 개별 뷰 홀더(ViewHolder)와 바인딩하여 각 항목을 RecyclerView에 표시한다.

 

 

 

 

 

먼저 이 데이터를,

{"status":"success","data":[{"id":1,"employee_name":"Tiger Nixon","employee_salary":320800,"employee_age":61,"profile_image":""},{"id":2,"employee_name":"Garrett Winters","employee_salary":170750,"employee_age":63,"profile_image":""},{"id":3,"employee_name":"Ashton Cox","employee_salary":86000,"employee_age":66,"profile_image":""},{"id":4,"employee_name":"Cedric Kelly","employee_salary":433060,"employee_age":22,"profile_image":""},{"id":5,"employee_name":"Airi Satou","employee_salary":162700,"employee_age":33,"profile_image":""},{"id":6,"employee_name":"Brielle Williamson","employee_salary":372000,"employee_age":61,"profile_image":""},{"id":7,"employee_name":"Herrod Chandler","employee_salary":137500,"employee_age":59,"profile_image":""},{"id":8,"employee_name":"Rhona Davidson","employee_salary":327900,"employee_age":55,"profile_image":""},{"id":9,"employee_name":"Colleen Hurst","employee_salary":205500,"employee_age":39,"profile_image":""},{"id":10,"employee_name":"Sonya Frost","employee_salary":103600,"employee_age":23,"profile_image":""},{"id":11,"employee_name":"Jena Gaines","employee_salary":90560,"employee_age":30,"profile_image":""},{"id":12,"employee_name":"Quinn Flynn","employee_salary":342000,"employee_age":22,"profile_image":""},{"id":13,"employee_name":"Charde Marshall","employee_salary":470600,"employee_age":36,"profile_image":""},{"id":14,"employee_name":"Haley Kennedy","employee_salary":313500,"employee_age":43,"profile_image":""},{"id":15,"employee_name":"Tatyana Fitzpatrick","employee_salary":385750,"employee_age":19,"profile_image":""},{"id":16,"employee_name":"Michael Silva","employee_salary":198500,"employee_age":66,"profile_image":""},{"id":17,"employee_name":"Paul Byrd","employee_salary":725000,"employee_age":64,"profile_image":""},{"id":18,"employee_name":"Gloria Little","employee_salary":237500,"employee_age":59,"profile_image":""},{"id":19,"employee_name":"Bradley Greer","employee_salary":132000,"employee_age":41,"profile_image":""},{"id":20,"employee_name":"Dai Rios","employee_salary":217500,"employee_age":35,"profile_image":""},{"id":21,"employee_name":"Jenette Caldwell","employee_salary":345000,"employee_age":30,"profile_image":""},{"id":22,"employee_name":"Yuri Berry","employee_salary":675000,"employee_age":40,"profile_image":""},{"id":23,"employee_name":"Caesar Vance","employee_salary":106450,"employee_age":21,"profile_image":""},{"id":24,"employee_name":"Doris Wilder","employee_salary":85600,"employee_age":23,"profile_image":""}],"message":"Successfully! All records has been fetched."}

 

 

 

이 창을 열어 넣은 후, copy를 눌러준다.

 

https://jsoneditoronline.org/#left=local.tusimo&right=local.qofoce

 

JSON Editor Online: edit JSON, format JSON, query JSON

JSON Editor Online is the original and most copied JSON Editor on the web. Use it to view, edit, format, repair, compare, query, transform, validate, and share your JSON data.

jsoneditoronline.org

 

 

 

 

중괄호 {} 는 object 데이터 타입이다.

대괄호 []는 array 데이터 타입이다.

 

 

 


Adapter.java 클래스

 

(EmployeeAdapter.java로 만들어주었다.)

package com.~.employee.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.~.employee.R;
import com.~.employee.model.Employer;

import java.text.DecimalFormat;
import java.util.ArrayList;

public class EmployerAdapter extends RecyclerView.Adapter<EmployerAdapter.ViewHolder> {

    Context context;
    ArrayList<Employer> employerArrayList;

    public EmployerAdapter(Context context, ArrayList<Employer> employerArrayList) {
        this.context = context;
        this.employerArrayList = employerArrayList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.employer_row, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Employer employer = employerArrayList.get(position);
        holder.txtName.setText(employer.name);
        holder.txtAge.setText(String.valueOf("나이 : "+employer.age+"세"));

        DecimalFormat formatter = new DecimalFormat("#,###");
        String strSalary = formatter.format(employer.salary);
        holder.txtSalary.setText(String.valueOf("연봉 : $"+strSalary));
    }

    @Override
    public int getItemCount() {
        return employerArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView txtName;
        TextView txtAge;
        TextView txtSalary;
        ImageView imgDelete;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            txtName = itemView.findViewById(R.id.txtName);
            txtAge = itemView.findViewById(R.id.txtAge);
            txtSalary = itemView.findViewById(R.id.txtSalary);
            imgDelete = itemView.findViewById(R.id.imgDelete);
        }
    }
}

 

 

 

 

MainActivity.java 클래스 (파싱하기)

package com.~.employee;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.yujinoh.employee.adapter.EmployerAdapter;
import com.yujinoh.employee.model.Employer;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    Button btnAdd;
    ProgressBar progressBar;
    EmployerAdapter adapter;

    //리사이클러뷰는 관련된 멤버변수 2개 더 작성해야 한다
    RecyclerView recyclerView;
    ArrayList<Employer> employerArrayList = new ArrayList<>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //다음 코드는 쌍으로 무조건 같이 작성
        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));

        btnAdd = findViewById(R.id.btnAdd);
        progressBar = findViewById(R.id.progressBar2);
        recyclerView = findViewById(R.id.recyclerView);

        btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // AddActivity를 띄운다
                Intent intent = new Intent(MainActivity.this, AddActivity.class);
                startActivity(intent);
            }
        });

        // 네트워크로부터 데이터를 받아온다
        // Volley 라이브러리를 이용한 네트워크 통신

        // 1. request queue 를 만든다
        RequestQueue queue = Volley.newRequestQueue(MainActivity.this);

        // 2. request(요청)을 만든다.
        // 데이터 타입은, 응답의 json 형식을 보고 결정한다.
        JsonObjectRequest request = new JsonObjectRequest(
                Request.Method.GET,
                "https://block1-image-test.s3.ap-northeast-2.amazonaws.com/employees.json",
                null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        // 프로그레스 바를 유저의 눈에서 사라지게 하는 코드
                        progressBar.setVisibility(View.GONE);

                        Log.i("EMPLOYEE MAIN", response.toString());

                        try {
                            String status = response.getString("status");
                            if(status.equals("success") == false){
                                Toast.makeText(MainActivity.this,
                                        "네트워크 에러",
                                        Toast.LENGTH_SHORT).show();
                                return;
                            }

                            JSONArray data = response.getJSONArray("data");

                            for(int i = 0 ; i < data.length() ; i++){
                                JSONObject row = data.getJSONObject(i);
                                int id = row.getInt("id");
                                String name = row.getString("employee_name");
                                int salary = row.getInt("employee_salary");
                                int age = row.getInt("employee_age");

                                Employer employer= new Employer(id, name, salary, age);
                                employerArrayList.add(employer);
                            }

                            // 어댑터를 만들고
                            adapter = new EmployerAdapter(MainActivity.this, employerArrayList);
                            // 리사이클러뷰에 어댑터를 적용하면 화면에 나온다
                            recyclerView.setAdapter(adapter);

                        } catch (JSONException e) {
                            Toast.makeText(MainActivity.this,
                                    "파싱 에러",
                                    Toast.LENGTH_SHORT).show();
                            return;
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        // 프로그레스 바를 유저의 눈에서 사라지게 하는 코드
                        progressBar.setVisibility(View.GONE);

                        Toast.makeText(MainActivity.this,
                                "네트워크 통신 에러",
                                Toast.LENGTH_SHORT).show();
                        Log.i("EMPLOYEE MAIN", error.toString());
                    }
                }
        );

        // 3. 네트워크로 보낸다.
        queue.add(request);

    }
}

 

 

 


Employer.java 클래스

package com.~.employee.model;

public class Employer {

    public int id;
    public String name;
    public int salary;
    public int age;

    public Employer(){

    }

    public Employer(int id, String name, int salary, int age) {
        this.id = id;
        this.name = name;
        this.salary = salary;
        this.age = age;
    }
}